Note:

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

Tutorial: Difference between revisions

From MoodleDocs
(Added link to https://docs.moodle.org/dev/Plugin_contribution_checklist#Strings in ===How to support over 100 languages===)
(45 intermediate revisions by 9 users not shown)
Line 3: Line 3:
This is a tutorial to help you learn how to write plugins for Moodle from start to finish, while showing you how to navigate the most important developer documentation along the way.
This is a tutorial to help you learn how to write plugins for Moodle from start to finish, while showing you how to navigate the most important developer documentation along the way.


PRE-REQUISITES:  We assume you are fairly comfortable with PHP in general and that you are able to install a database and web server on your local machine.
PRE-REQUISITES:  We assume you are fairly comfortable with [[PHP FAQ|PHP]] in general and that you are able to [[:en:Installing AMP|install a database and web server]] on your local machine.  


Code examples can be found on github at https://github.com/abgreeve/devcourse where a working plugin is located.
If you need to learn PHP, you can see one PHP tutorial at http://www.w3schools.com/php/default.asp, another at http://php.net/manual/en/tutorial.php and several videos in YouTube at https://www.youtube.com/results?search_query=learn+php.  


==Background==
==Background==
===What's in the box===
If you [http://download.moodle.org/ download] Moodle source code or clone it from [https://github.com/moodle/moodle git], you will see a bunch of files and folders. This code consists of [[Core_APIs|Moodle core]] (that consists of the Very core and Core components), [[Moodle_libraries_credits|third party libraries]] and [[Plugin_types|plugins]]. Their mixed locations can be quite confusing at first but as you start working with it it will become more clear. Moodle developers should avoid modifications of the third party libraries (unless required) and core can never call methods defined in plugins. See also [[Communication Between Components]]
===Setting up your development environment===
===Setting up your development environment===
* Install Git. View the link below for basic information about git and Moodle.
* [[Setting up development environment]]: PHP server, database...
* Clone Moodle.
* Moodle uses Git for development. View the following link for basic information about Git and Moodle: [[Git for developers]]
* Create branches and push to a public repository such as github.
====Setting up git to track your plugin====
Once you have Moodle cloned and installed on you machine what now? The next step is to create a repository to store your plugin.
# Log into your github account (https://github.com).
# Create a new repository. (https://help.github.com/articles/create-a-repo/)
#* When naming your repository it is good to follow the following standard "moodle-{component}_{plugin name}" e.g. moodle-mod_newmodule (this exists - https://github.com/moodlehq/moodle-mod_newmodule)
# Set up git to upload to this repository.
## Create the directory that contains your plugin (if we were creating the plugin above, we would create a directory called "newmodule").
## Initialise git <code>git init</code>.
## Set the remote to push changes to <code>git remote add origin https://github.com/{your github user name}/{repository name}</code>. The "origin" part is the name given for the remote name and can be changed to anything else such as "upstream".
 
====Creating your first commit====
At the moment you are on a master branch. Creating a branch is a good idea so that you can try out ideas and when you are satisfied with your code merge the branch into master.
# Create a new branch <code>git checkout -b {name of the branch}</code> The name of the branch is up to you. Something descriptive is recommended.
# When you are happy with you branch and want to upload your code to the repository you can merge the branch with master. <code>git merge {branch name}</code>Now to send the new master branch to the repository. <code>git push origin master</code>
 
You code is now uploaded to your repository on github and others can now easily download and contribute to your code.
 
links
 
* https://docs.moodle.org/dev/Git_for_developers


===The Moodle development framework===
===The Moodle development framework===
Line 40: Line 22:
links
links


* https://moodle.org/plugins/index.php
* https://moodle.org/plugins/
* https://docs.moodle.org/dev/Plugin_types
* [[Plugin types]]


==Let's make a plugin==
==Let's make a plugin==
===The skeleton of your plugin===
===The skeleton of your plugin===
[[{{ns:file}}:plugin-skeleton.png]]
This image shows directories and files that you will find in most plugins.


* '''plugin''' would actually be the name of your plugin. This also applies to the file in "lang/en/".
The code of a plugin is organised into multiple different files and directories within a single root directory. All plugins follow the same directory and file structure.
* '''classes''' contains classes used in your plugin.
* '''db''' has database related files and also capabilities (access.php).
* '''lang''' The language directory.
* '''lib.php''' base library file for some hooks and callbacks.
* '''version.php''' contains bare basic information about the plugin.


links
Links


* [[Plugin files]]
* [[Plugin files]] - Provides a list of required and common plugins files along with their location and purpose.
* https://docs.moodle.org/dev/Moodle_architecture
* https://docs.moodle.org/dev/Plugin_types
* https://moodle.org/plugins/


===Basic page structure===
===Basic page structure===


* For a page that is displaying content to a user we have the following sections:
The link below explains how to create and display a simple page in Moodle.
** Required files.
** POST and GET variables retrieved using required_param and optional_param.
** context.
** navigation setup.
** title, headings, headers.
** content.
** footers.
 
<code php>
// Required files.
require_once(__DIR__ . '/config.php');
// Required and optional parameters.
$id = required_param('id', PARAM_INT);
$text = optional_param('text', '', PARAM_ALPHA);
 
// Setting context for the page.
$PAGE->set_context(context_system::instance());
// URL is created and then set for the page navigation.
$url = new moodle_url('/test.php');
$PAGE->set_url($url);
// Heading, headers, page layout.
$PAGE->set_heading(get_string('hello'));
$PAGE->set_pagelayout('standard');
echo $OUTPUT->header();
// Displaying basic content.
echo html_writer::tag('p', $text);
// Display the footer.
echo $OUTPUT->footer();
</code>


links
links


* https://docs.moodle.org/dev/Page_API
* [[Page API]]
* https://docs.moodle.org/dev/lib/weblib.php_moodle_url


===How to support over 100 languages===
===Multiple languages support===
* Language files are stored in the "lang" directory. English strings would be found in "lang/en". Each language contains a file named after the plugin which contains all of the strings. For example the language strings for the assignment activity are found in "mod/assign/lang/en/assign.php".
Moodle has a mechanism for displaying given text string in multiple languages, depending on the user's preferred language and the site configuration. Plugin authors must define all the text strings used by the plugin in the default English language. That is then used as a reference for translations to other languages.
* Moodle's default is Australian English. American English is in a separate language pack (en_us).
* get_string() is used in most cases for displaying text.
* lang_string() is used in situations where the text may not necessarily be displayed.


<code php>
* [[String API]]
// Declaration in language file (lang/en/{pluginname}.php)
$string['nameofstring'] = 'Actual string';
</code>
 
The get_string() function takes four parameters, but in this example we are only filling in the first two. The last two parameters are optional. The first parameter is the identifier for the string. The second is the component.
The component will be the name of the language file.
The following example shows a string in the badges block.
<code php>
// Use of string in code.
echo html_writer::tag('p', get_string('numbadgestodisplay', 'block_badges'));
</code>


===Moodle file structure===
==== Automatic Class Loading ====
Automatic class loading helps us to automatically include class files as and when they are required instead of manually including them everytime. Moodle supports automatic class loading. See the link below for the explanation of rules associated with it -


links
links


* https://docs.moodle.org/dev/String_API
[[ Automatic class loading]]
* https://docs.moodle.org/dev/Places_to_search_for_lang_strings
* https://docs.moodle.org/31/en/Language_customisation
* https://docs.moodle.org/dev/Plugin_contribution_checklist#Strings


===Add content to your page===
==== Callbacks ====
* Content for a page is added through renderers.
You can add a lot of features to your plugin by providing certain callbacks that Moodle expects to be present in your plugin's lib.php file. A detailed list can be found at -
* Renderers are typically stored in the "classes/output" directory.
* Putting content in renderers allows themers to override the visual display of the content.
* Very basic information is presented using the html_writer class.
* In most cases templates should be used.
* templates are stored in the "templates" directory. The templates use mustache files.
* Mustache files allow for more generic html with placeholders inserted, that inserts the data (context) at run time.


The example used below is an admin tool and would be located under admin/tool.
links


Step One: Create a class for rendering. This class collects information to display and has a method for formatting that information into a format that the template will understand.
[[ Callbacks ]]


'''devcourse/classes/output/developer_course_main_page.php'''
==== Plugin types ====
Moodle supports a wide range of plugin types. The complete list and location to place these plugins can be found at -


<code php>
links
namespace tool_devcourse\output;
defined('MOODLE_INTERNAL') || die();


use renderable;
[[ Plugin types ]]
use renderer_base;
use templatable;
use stdClass;


==== Core APIs ====
Moodle provides apis for a plugin to interact with core and other external systems. For example you don't have to manually do any SQL queries, Moodle provides it's own DDL and DML layers. The link below lists all major core apis in Moodle -


class developer_course_main_page implements renderable, templatable {
links


  protected $comment;
[[ Core APIs ]]


    /**
==== Browser accessible pages ====
    * Construct this renderable.
Any php file in your plugin will either be browser accessible or be an internal file.  
    * @param int $courseid The course record for this page.
    */
    public function __construct($comment) {
        $this->comment = $comment;
    }


    /**
For browser accessible pages you must include config.php with code something similar to this -
    * Export this data so it can be used as the context for a mustache template.
<code php>
    *
require_once('../../config.php');
    * @param renderer_base $output Renderer base.
    * @return stdClass
    */
    public function export_for_template(renderer_base $output) {
        $data = new stdClass();
        $data->comment = $this->comment;
        return $data;
    }
}
</code>
</code>


 
For internal files the code should use the following -
Step Two: To render this information a custom renderer is created for the plugin. This renderer class must extend plugin_renderer_base.
 
'''devcourse/classes/output/renderer.php'''
 
<code php>
<code php>
namespace tool_devcourse\output;
defined('MOODLE_INTERNAL') || die();
defined('MOODLE_INTERNAL') || die();
use plugin_renderer_base;
use renderable;
class renderer extends plugin_renderer_base {
    /**
    * Defer to template.
    *
    * @param developer_course_main_page $page
    *
    * @return string html for the page
    */
    public function render_developer_course_main_page(developer_course_main_page $page) {
        $data = $page->export_for_template($this);
        return parent::render_from_template('tool_devcourse/developer_course_main_page', $data);
    }
}
</code>
</code>


===Add basic content to your page===
* Content for a page is added through renderers.
* Renderers are typically stored in the "classes/output" directory.
* Putting content in renderers allows themers to override the visual display of the content.
* Very basic information is presented using the html_writer class.


Step three: A mustache template is to then be created. The information is sent to the template and at this point the information is known as the context (not to be confused with the normal definition of context throughout Moodle).
links


'''devcourse/templates/developer_course_main_page.mustache'''
* [[Renderer]]
<code html>
{{!
    @template tool_devcourse/developer_course_main_page


    Example context (json):
=== Content with templates ===
    {
* In most cases when displaying content, templates should be used.
        "comment": "Example comment for the context"
* templates are stored in the "templates" directory. The templates use mustache files.
    }
* Mustache files allow for more generic html with placeholders inserted, that inserts the data (context) at run time.
}}
<h2>{{#str}}maintitle, tool_devdoc{{/str}}</h2>
<div>{{comment}}</div>
</code>
This shows an extremely simple mustache template with one item in the context (comment). It also shows how strings are defined in the template.
 
Step four: To actually have this template be displayed we get the custom renderer. This chunk of code would be located in a place such as devcourse/index.php after the appropriate setup outlined in the [[Tutorial#Basic_page_structure|basic page structure]].
<code php>
$output = $PAGE->get_renderer('tool_devcourse');
//Then we get the class for rendering and provide it with information (if needed).
$randomcomment = 'This comment is random';
$page = new \tool_devdoc\output\developer_course_main_page($randomcomment);
//Finally we echo out the template
echo $output->render($page);
</code>


links
links


* https://docs.moodle.org/dev/Output_API
* [[Templates]]
* https://docs.moodle.org/dev/Output_functions
* https://docs.moodle.org/dev/Templates
* https://docs.moodle.org/dev/Output_renderers
* https://docs.moodle.org/dev/Renderer
* https://docs.moodle.org/dev/Overriding_a_renderer


===Adding your plugin into Moodle's navigation===
===Adding your plugin into Moodle's navigation===
Line 258: Line 122:
links
links


* https://docs.moodle.org/dev/Navigation_API
* [[Navigation API]]
* https://docs.moodle.org/31/en/Navigation
* [[:en:Navigation]]


===Database queries===
===Database queries===
Line 268: Line 132:
Example call to retrieve data from the course table.
Example call to retrieve data from the course table.
<code php>
<code php>
global $DB;
$courses = $DB->get_records('course', null, '', 'id, category, fullname, shortname');
$courses = $DB->get_records('course', null, '', 'id, category, fullname, shortname');
</code>
</code>
Line 302: Line 167:
links
links


* https://docs.moodle.org/dev/Database
* [[Database]]
* https://docs.moodle.org/dev/Data_manipulation_API
* [[Data manipulation API]]


===Creating your own database tables===
===Creating your own database tables===
Line 320: Line 185:


links
links
* https://docs.moodle.org/dev/XMLDB_editor
* [[XMLDB editor]]
* https://docs.moodle.org/dev/Using_XMLDB
* [[Using XMLDB]]
* https://docs.moodle.org/dev/XMLDB_Documentation
* [[XMLDB Documentation]]
* https://docs.moodle.org/dev/Upgrade_API
* [[Upgrade API]]
* https://docs.moodle.org/dev/XMLDB_introduction
* [[XMLDB introduction]]


===Supporting access permissions: roles, capabilities and contexts===
===Supporting access permissions: roles, capabilities and contexts===
Line 337: Line 202:


links
links
* https://docs.moodle.org/dev/Access_API
* [[Access API]]
* https://docs.moodle.org/dev/Roles#Context
* [[Roles#Context]]
* https://docs.moodle.org/31/en/Category:Capabilities
* [[:en:Category:Capabilities]]
* https://docs.moodle.org/31/en/Roles_and_permissions
* [[:en:Roles and permissions]]


===Adding web forms===
===Adding web forms===
Line 349: Line 214:
links
links


* https://docs.moodle.org/dev/Form_API
* [[Form API]]
* https://docs.moodle.org/dev/lib/formslib.php_Form_Definition
* [[lib/formslib.php Form Definition]]
* https://docs.moodle.org/dev/Fragment
* [[Fragment]]


===Maintaining good security===
===Maintaining good security===
Line 359: Line 224:
links
links


* https://docs.moodle.org/dev/lib/formslib.php_Form_Definition#Most_Commonly_Used_PARAM_.2A_Types
* [[Security]]
* https://docs.moodle.org/dev/Output_functions#p.28.29_and_s.28.29
* [[lib/formslib.php Form Definition#Most Commonly Used PARAM .2A Types]]
* [[Output functions#p.28.29 and s.28.29]]


===Handling files===
===Handling files===
Line 368: Line 234:
links
links


* https://docs.moodle.org/dev/File_API
* [[File API]]
* https://docs.moodle.org/dev/File_API_internals
* [[File API internals]]
* https://docs.moodle.org/dev/Using_the_File_API_in_Moodle_forms
* [[Using the File API in Moodle forms]]


===Adding Javascript===
===Adding Javascript===
Line 384: Line 250:
links
links


* https://docs.moodle.org/dev/Javascript_Modules
* [[Javascript Modules]]
* https://docs.moodle.org/dev/jQuery
* [[jQuery]]
* https://docs.moodle.org/dev/Javascript_FAQ
* [[Javascript FAQ]]
* https://docs.moodle.org/dev/JavaScript_guidelines
* [[JavaScript guidelines]]
* https://docs.moodle.org/dev/Grunt
* [[Grunt]]


===Adding events and logging===
===Adding events and logging===
Line 397: Line 263:
links
links


* https://docs.moodle.org/dev/Event_2
* [[Event 2]]
* https://docs.moodle.org/dev/Logging_2
* [[Logging 2]]
 
===Accessibility===
 
Accessibility is an important consideration while developing a plugin to make sure your plugin is accessible to all users and doesn't discriminate against users with disablities. This often is a mandated requirement in many countries. The links below explain common practices that we follow at Moodle to make the interface more accessible.


links
* [[Accessibility]]
* [[Usability]]
===Web Services and AJAX===
===Web Services and AJAX===
* Moodle web services uses the external functions API.
* Moodle web services uses the external functions API.
Line 416: Line 289:
links
links


* https://docs.moodle.org/dev/External_functions_API
* [[External functions API]]
* https://docs.moodle.org/dev/Adding_a_web_service_to_a_plugin
* [[Adding a web service to a plugin]]
* https://docs.moodle.org/dev/Web_services_API
* [[Web services API]]


===Using caching to improve performance===
===Using caching to improve performance===
Line 429: Line 302:
links
links


* https://docs.moodle.org/dev/The_Moodle_Universal_Cache_(MUC)
* [[The Moodle Universal Cache (MUC)]]
* https://docs.moodle.org/31/en/MUC_FAQ
* [[:en:MUC FAQ]]
* https://docs.moodle.org/31/en/Caching
* [[:en:Caching]]


===Supporting backup and restore===
===Supporting backup and restore===
Line 442: Line 315:
links
links


* https://docs.moodle.org/31/en/Backup_and_restore_FAQ
* [[Backup 2.0 for developers]] - provides an example of step-by-step implementation of backup support to your plugin
* Could not find dev docs.
* [[:en:Backup and restore FAQ]]


===Supporting automated testing===
===Supporting automated testing===
Line 457: Line 330:
links
links


* https://docs.moodle.org/dev/Writing_PHPUnit_tests
* [[Writing PHPUnit tests]]
* https://docs.moodle.org/dev/PHPUnit
* [[PHPUnit]]
* https://docs.moodle.org/dev/Acceptance_testing
* [[Acceptance testing]]
* https://docs.moodle.org/dev/Behat_integration
* [[Behat integration]]


==Publishing your plugin==
==Publishing your plugin==
Line 471: Line 344:




=TODO=
==TODO==
 
Finishing this tutorial:
Finishing this tutorial:
# About one or two screens for each section with a very generic overview for beginners, containing links to relevant docs WITH COMMENTS ABOUT QUALITY, USEFULNESS, CAVEATS etc.
# About one or two screens for each section with a very generic overview for beginners, containing links to relevant docs WITH COMMENTS ABOUT QUALITY, USEFULNESS, CAVEATS etc.
# Go through all the linked pages and make sure they are current and accurate.
# Go through all the linked pages and make sure they are current and accurate.
# Add a worked example to this page, so that each section has suggestions about things to add to the admin tool being built as an exercise.  If the code is long, it could be placed on separate pages.  A good reference for style is [[Moodle_Mobile_Developing_a_plugin_tutorial]] and [[Blocks]].
# Add a worked example to this page, so that each section has suggestions about things to add to the admin tool being built as an exercise.  If the code is long, it could be placed on separate pages.  A good reference for style is [[Mobile_support_for_plugins]] and [[Blocks]].
 
==See also==
* See [https://moodle.org/mod/forum/discuss.php?d=355789 this (july 2017) forum thread ] about Getting Started with Moodle Development.
* See [https://moodle.org/mod/forum/discuss.php?d=352360 this (may 2017) forum thread] about Getting Started with Moodle Development.
* MoodleBites for Developers - completely online courses [https://www.moodlebites.com/mod/page/view.php?id=24546 Level 1] and [https://www.moodlebites.com/mod/page/view.php?id=19542 Level 2] are designed to get new developers up-to-speed with Moodle development, and are run online by HRDNZ (Certified Moodle Partner since 2006).
 
See also these older tutorials:


=See also these older tutorials =
* [[Blocks|A Step-by-step Guide To Creating Blocks]]  
* [[Blocks|A Step-by-step Guide To Creating Blocks]]  
* [[NEWMODULE Tutorial]]
* [[NEWMODULE Tutorial]]
* [http://dev.moodle.org Introduction to Moodle programming (based on Moodle 1.8)]
* [[Mobile_support_for_plugins|Moodle Mobile plugin tutorial]]
* [[Moodle_Mobile_Developing_a_plugin_tutorial|Moodle Mobile plugin tutorial]]
* [[Category:Tutorial|Other tutorials in these docs]]
* [https://docs.moodle.org/dev/Category:Tutorial Other tutorials in these docs]
 
==Any questions?==
 
If you have any questions, you're welcome to post in the [https://moodle.org/mod/forum/view.php?id=55 General developer forum] on moodle.org


[[Category:Tutorial]]
[[Category:Tutorial]]

Revision as of 03:08, 5 February 2019

Welcome to Moodle development!

This is a tutorial to help you learn how to write plugins for Moodle from start to finish, while showing you how to navigate the most important developer documentation along the way.

PRE-REQUISITES: We assume you are fairly comfortable with PHP in general and that you are able to install a database and web server on your local machine.

If you need to learn PHP, you can see one PHP tutorial at http://www.w3schools.com/php/default.asp, another at http://php.net/manual/en/tutorial.php and several videos in YouTube at https://www.youtube.com/results?search_query=learn+php.

Background

What's in the box

If you download Moodle source code or clone it from git, you will see a bunch of files and folders. This code consists of Moodle core (that consists of the Very core and Core components), third party libraries and plugins. Their mixed locations can be quite confusing at first but as you start working with it it will become more clear. Moodle developers should avoid modifications of the third party libraries (unless required) and core can never call methods defined in plugins. See also Communication Between Components

Setting up your development environment

The Moodle development framework

What type of plugin are you developing?

  • Moodle has lots of different types of plugins.
  • There are 24 different categories of plugin listed on the moodle plugin database. Before starting check here to see if someone else has not already created what you are looking for. Perhaps you could contribute to their plugin instead of creating a new one.

links

Let's make a plugin

The skeleton of your plugin

The code of a plugin is organised into multiple different files and directories within a single root directory. All plugins follow the same directory and file structure.

Links

  • Plugin files - Provides a list of required and common plugins files along with their location and purpose.

Basic page structure

The link below explains how to create and display a simple page in Moodle.

links

Multiple languages support

Moodle has a mechanism for displaying given text string in multiple languages, depending on the user's preferred language and the site configuration. Plugin authors must define all the text strings used by the plugin in the default English language. That is then used as a reference for translations to other languages.

Moodle file structure

Automatic Class Loading

Automatic class loading helps us to automatically include class files as and when they are required instead of manually including them everytime. Moodle supports automatic class loading. See the link below for the explanation of rules associated with it -

links

Automatic class loading

Callbacks

You can add a lot of features to your plugin by providing certain callbacks that Moodle expects to be present in your plugin's lib.php file. A detailed list can be found at -

links

Callbacks

Plugin types

Moodle supports a wide range of plugin types. The complete list and location to place these plugins can be found at -

links

Plugin types

Core APIs

Moodle provides apis for a plugin to interact with core and other external systems. For example you don't have to manually do any SQL queries, Moodle provides it's own DDL and DML layers. The link below lists all major core apis in Moodle -

links

Core APIs

Browser accessible pages

Any php file in your plugin will either be browser accessible or be an internal file.

For browser accessible pages you must include config.php with code something similar to this - require_once('../../config.php');

For internal files the code should use the following - defined('MOODLE_INTERNAL') || die();

Add basic content to your page

  • Content for a page is added through renderers.
  • Renderers are typically stored in the "classes/output" directory.
  • Putting content in renderers allows themers to override the visual display of the content.
  • Very basic information is presented using the html_writer class.

links

Content with templates

  • In most cases when displaying content, templates should be used.
  • templates are stored in the "templates" directory. The templates use mustache files.
  • Mustache files allow for more generic html with placeholders inserted, that inserts the data (context) at run time.

links

Adding your plugin into Moodle's navigation

  • The moodle navigation system has hooks which allows plugins to add links to the navigation menu.
  • Hooks are located in lib.php. Try to keep lib.php as small as possible as this file is included on every page. Put classes and functions elsewhere.
  • Course navigation extension example:

function tool_devcourse_extend_navigation_course($navigation, $course, $coursecontext) {

   $url = new moodle_url('/admin/tool/devcourse/index.php');
   $devcoursenode = navigation_node::create('Development course', $url, navigation_node::TYPE_CUSTOM, 'Dev course', 'devcourse');
   $navigation->add_node($devcoursenode);

}

links

Database queries

  • Moodle has a generic database query library. Behind this library are additional libraries which allow Moodle to work with MySQL, PostgreSQL, Oracle, SQL Server, and Maria DB.
  • Where possible it is advisable to use the predefined functions rather than write out SQL. Writing SQL has a greater chance of not working with one of the supported databases.
  • The return of the select functions tends to be an object or an array of objects.

Example call to retrieve data from the course table. global $DB; $courses = $DB->get_records('course', null, , 'id, category, fullname, shortname'); Example of data returned from the above code. Array (

   [43] => stdClass Object
       (
           [id] => 43
           [category] => 1
           [fullname] => XX -Test 5
           [shortname] => xxt5
       )
   [5] => stdClass Object
       (
           [id] => 5
           [category] => 1
           [fullname] => With the glossary
           [shortname] => wtg
       )
   [39] => stdClass Object
       (
           [id] => 39
           [category] => 1
           [fullname] => XX - Test 1
           [shortname] => xxt1
       )

)

links

Creating your own database tables

  • We create our database tables in Moodle using the XMLDB editor. This is located in the administration block "Site administration | Development | XMLDB editor".
  • The {plugin}\db directory needs to have write access for the XMLDB editor to be most effective.
  • XMLDB editor creates an install.xml file in the db directory. This file will be loaded during the install to create your tables.
  • XMLDB editor will produce php update code for adding and updating moodle database tables.

The XMLDB main page.

xmldb-main.png

Upgrade code generated by the XMLDB

xmldb-upgrade-code.png

links

Supporting access permissions: roles, capabilities and contexts

  • Capabilities are controlled in "access.php" under the "db" directory.
  • This file has an array of capabilities with the following:
    • name
    • possible security risks behind giving this capability.
    • The context that this capability works in.
    • The default roles (teacher, manager, student, etc) that have this capability.
    • Various other information.
  • These capabilities are checked in code to allow access to pages, sections, and abilities (saving, deleting, etc).

links

Adding web forms

  • Moodle has it's own forms library.
  • The forms lib includes a lot of accessibility code, and error checking, by default.
  • Moodle forms can be displayed in JavaScript using 'fragments'.

links

Maintaining good security

  • Use the sesskey when directing to pages to do actions.
  • Use the appropriate filters when retrieving parameters

links

Handling files

  • Files are conceptually stored in file areas.
  • Plugins can only access files from it's own component.

links

Adding Javascript

  • Moodle is currently using jquery and AMD (Asynchronous Module Definition).
  • JavaScript files are located in the "amd/src" directory.
  • Use grunt to build your JavaScript.
  • Include your JavaScript in php files as follows:

$this->page->requires->js_call_amd('{JScriptfilename}');

  • Can also be included in mustache templates.

links

Adding events and logging

  • All logging in moodle is done through the events system.
  • New events should be located in the "classes/event" directory.
  • It is possible to create observers and subscribe to events.

links

Accessibility

Accessibility is an important consideration while developing a plugin to make sure your plugin is accessible to all users and doesn't discriminate against users with disablities. This often is a mandated requirement in many countries. The links below explain common practices that we follow at Moodle to make the interface more accessible.

links

Web Services and AJAX

  • Moodle web services uses the external functions API.
  • The recommended way to make AJAX requests is to use the ajax AMD file which uses the external functions API.
  • External functions should be located in the "classes/external.php" file.
  • A list of services should be included in "db/services.php". This file is required to register the web services with Moodle.
  • The services list is an array which contains:
    • classname Name of the external class.
    • methodname The name of the external function.
    • classpath system path to the external function file.
    • description Description of the function
    • type Create, read, update, delete
    • ajax Can this function be used with ajax?
    • capabilities Capabilities required to use this function.

links

Using caching to improve performance

  • The main cache used by moodle is the Moodle Universal Cache (MUC).
  • The MUC has several cache definitions -
    • Request cache
    • Session cache
    • Application

links

Supporting backup and restore

  • Supporting backup and restore requires creating several files in the 'backup/moodle2' directory.
  • Back requires a class to extend the backup_task of some sort. There may be a specific plugin task to extend.
  • Restore requires a class to extend the restore_task of some sort. There may be a specific plugin task to extend.
  • The restore steps lib defines the structure of the plugin to be restored.
  • The backup steps lib defines steps, settings, attributes, etc.

links

Supporting automated testing

  • Moodle has two types of automated testing: php unit tests, and behat tests.
  • Unit tests are for testing functions.
  • Behat tests runs through scenarios.
    • Behat tests follows a script and navigates through moodle pages.
  • unit tests should be located in the "tests" directory.
  • behat tests should be located in the "tests/behat" directory.
  • Tests located in these directories will be run through when a full test run is initiated.
  • behat tests are actually feature files and end with the extension ".feature".

links

Publishing your plugin

Adding your plugin to moodle.org

  • publish your plugins at https://moodle.org/plugins/
  • Publishing plugins on the moodle site leads you through a bunch of steps that need to be completed in order for the plugin to be approved and published.
  • Plugins will be run through a pre-checker to give suggestions about possible issues with the code.

Supporting your plugin

TODO

Finishing this tutorial:

  1. About one or two screens for each section with a very generic overview for beginners, containing links to relevant docs WITH COMMENTS ABOUT QUALITY, USEFULNESS, CAVEATS etc.
  2. Go through all the linked pages and make sure they are current and accurate.
  3. Add a worked example to this page, so that each section has suggestions about things to add to the admin tool being built as an exercise. If the code is long, it could be placed on separate pages. A good reference for style is Mobile_support_for_plugins and Blocks.

See also

  • See this (july 2017) forum thread about Getting Started with Moodle Development.
  • See this (may 2017) forum thread about Getting Started with Moodle Development.
  • MoodleBites for Developers - completely online courses Level 1 and Level 2 are designed to get new developers up-to-speed with Moodle development, and are run online by HRDNZ (Certified Moodle Partner since 2006).

See also these older tutorials:

Any questions?

If you have any questions, you're welcome to post in the General developer forum on moodle.org