Introduction

According to the API Documentation, Events are atomic pieces of information describing something that happened in Moodle. Events are primarily the result of user actions, but could also be the result of the cron process or administration actions undertaken via the command line. When an action takes place , an event is created by a core API or plug-in. The Events system then disseminates this event information to observers registered for this event. In this way, the events system acts as a communication backbone throughout the Moodle system. Event observers can not modify event data or interrupt the dispatching of events, it is a one-way communication channel.

About Moodle

Moodle is an open-source tool that provides a platform for teachers and learners to share and interact with educative content. Organizations such as universities use it to serve learning content to their students and also conduct online assessments such as quizzes and others. You can learn more about Moodle here.

Since it is open-source, you can install Moodle on your server and run it under your domain. You can also customize it according to your organization’s theme. Another perk of it being open source is that you can create a local plug-in to enable you to extend functionalities. Therefore, this guide is going to focus on how you can create a local plug-in within Moodle by using Event Listeners as our case study. I will also provide you with links to resources to help you set up and run Moodle on your server.

This write-up is on Moodle event listener as local a plug-in. It will be helpful to developers who would love to monitor events occurring on their Moodle sites remotely or those who build their third-party applications that interact with Moodle.

The code is hosted on GitHub. The banner image used in this article was designed by me using a template from Canva.

Glossary

Moodle: A free and open-source learning or course management system. You can learn more about it here.

Plugin. A software package that is used to extend the functionalities of an existing system. In our case, a software package to enable us to extend the functionalities of Moodle. 

Event Listeners: Functions or entities that observe changes or activities in a software system. Events can be a new user created, a user log in, a new course added, etc. Moodle APIs: Moodle has a list of APIs that developers can use to interact with the platform. Among them is a collection of the Event Listeners API. Check a full list here.

Step-By-Step Procedure

Now that we know a thing or two about Moodle, let’s create our Moodle event listener as a local a plug-in.

Step 1. Install and run Moodle on your local machine or server.

Follow the step-by-step guide. Specific instruction for Windows installation is found here. Following this guide, you won’t have to install XAMPP or WAMPP servers separately, as Moodle provides them in the downloaded zipped folder.

Step 2. Create the local plug-in folder structure.

By now your Moodle site is running on your local machine (http://localhost:8000, if you are running it on localhost). If you are at this stage, great. Let’s now create our plug-in. Go to the location where your Moodle folder is. Inside the Moodle Folder, you should be able to see the following contents.

All the codes and files are stored inside the “server” folder. Let’s navigate as follows; server > moodle > local. Inside the “local” folder is where all local plug-ins are created.

Let us now start creating our new plug-in. Inside the local folder, let us create a new folder named “test”. The name of this folder becomes the name of your plug-in, so choose an appropriate name.

Our plug-in is, by Moodle convention, required to have a version.php file. Inside our “test” folder, let us create a file version.php. Something to note is that Moodle is written in PHP and so, all our codes here have to be in PHP. The content of version.php is as shown below.

<?php
defined('MOODLE_INTERNAL') || die();
$plugin->version = 20211101;
$plugin->requires = 2015111000;
$plugin->component = 'local_test';
view raw version.php hosted with ❤ by GitHub

Moodle identifies our plug-in using this file. The contents are;

  • version; a set of numbers that identifies the current version of our plug-in. The recommended format is “year-month-a numerical figure”. In our case, it’s 20211101. The last two digits have to be incremented whenever we update our plug-in for moodle to detect the updates.
  • requires; This is the moodle version that the plug-in requires to run.
  • component; the location of our plug-in.

Step 3. Add Event Listener functionalities to our plug-in by creating events and observers

Inside the “test” folder, alongside version.php, let’s add two folders classes and db. Again, note that the names of the folders should be how we have named them. Inside the “db” folder, let us create a file, events.php. This is where we write our event names and callbacks. Moodle provides us with API documentation that lists all the events. They are found here.

Below is the content of events.php.
<?php
defined('MOODLE_INTERNAL') || die();
$observers = array(
//Users
array(
'eventname' => '\core\event\user_created',
'callback' => 'local_test_observer::user_created',
),
array(
'eventname' => '\core\event\user_deleted',
'callback' => 'local_test_observer::user_deleted',
),
array(
'eventname' => '\core\event\user_password_updated',
'callback' => 'local_test_observer::user_password_updated',
),
array(
'eventname' => 'core\event\user_updated',
'callback' => 'local_test_observer::user_updated',
),
//Chapters
array(
'eventname' => '\mod_book\event\chapter_created',
'callback' => 'local_test_observer::chapter_created',
),
array(
'eventname' => '\mod_book\event\chapter_deleted',
'callback' => 'local_test_observer::chapter_deleted',
),
array(
'eventname' => '\mod_book\event\chapter_updated',
'callback' => 'local_test_observer::chapter_updated',
),
//Course
array(
'eventname' => '\core\event\course_created',
'callback' => 'local_test_observer::course_created',
),
array(
'eventname' => '\core\event\course_deleted',
'callback' => 'local_test_observer::course_deleted',
),
array(
'eventname' => '\core\event\course_module_created',
'callback' => 'local_test_observer::course_module_created',
),
array(
'eventname' => '\core\event\course_module_deleted',
'callback' => 'local_test_observer::course_module_deleted',
),
array(
'eventname' => '\core\event\course_module_updated',
'callback' => 'local_test_observer::course_module_updated',
),
array(
'eventname' => '\core\event\course_restored',
'callback' => 'local_test_observer::course_restored',
),
array(
'eventname' => '\core\event\course_updated',
'callback' => 'local_test_observer::course_updated',
),
);
view raw events.php hosted with ❤ by GitHub

 

From the content, we can note that each event and its callback is found inside the array(‘eventname’ => ‘’, ‘callback’ => ‘’) function. Let’s use the first event for an explanation.

We notice from the “eventname” that this is a “user is created” event. We, therefore, pass \core\event\user_created as an argument here. (For every event, the parameters to pass are provided in this API documentation. Therefore, you should just be knowing the event you want to monitor, look it up in the API doc, then pass it as an argument to the eventname parameter). The second parameter is the callback. This points to the observer function for this particular event. This function is called whenever this event occurs. Again, for the first event “user is created”, we can notice that the callback points to the function “user_created” found in the class “local_test_observer” contained in the file observer.php

Ooh wait, we don’t yet have our observer.php. Let us create it now. Inside the folder “classes”, let’s create the file observer.php.

Below is the content of the file.
<?php
class local_test_observer
{
//Users observers
public static function user_created(\core\event\user_created $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function user_deleted(\core\event\user_deleted $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function user_password_updated(\core\event\user_password_updated $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function user_updated(\core\event\user_updated $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
//Chapter observers
public static function chapter_created(\mod_book\event\chapter_created $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function chapter_deleted(\mod_book\event\chapter_deleted $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function chapter_updated(\mod_book\event\chapter_updated $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
//Course observers
public static function course_created(\core\event\course_created $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function course_deleted(\core\event\course_deleted $event)
{
$event_data = $event->get_data();
var_dump($event_data);
die();
}
public static function course_module_created(\core\event\course_module_created $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function course_module_deleted(\core\event\course_module_deleted $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function course_module_updated(\core\event\course_module_updated $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function course_restored(\core\event\course_restored $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
public static function course_updated(\core\event\course_updated $event)
{
$event_data = $event->get_data();
var_dump(json_encode($event_data));
die();
}
}
view raw observer.php hosted with ❤ by GitHub

From the content, we notice that this file contains callback functions for all the events in the events.php. It is here where we can write whatever we want to happen whenever a particular event happens. It can be anything from updating dashboards, firing emails, or even sending data to another application that is interacting with moodle.

In my case, I am just fetching the event data and printing them on the browser using the PHP’s var_dump() function.

Due to this guide being for learning purposes, I wrote code for a few events. For any other event, the structure remains the same. Again, look up all the supported events from the API documentation.

Great, that is it with our plug-in code. Very brief but powerful.

Step 4. Install our new Moodle events listener plug-in

If we did everything right in the previous steps, Moodle detects our plug-in. When we go back to our running Moodle site, we should be able to see the screen below. This shows that a new plug-in has been detected and needs to be installed.

How to create a Moodle event listener as a local plugin

When presented with this screen, scroll down and click “Continue”. You will then be presented with the screen below. Impressive, we can see information about our new plug-in.

How to create a Moodle event listener as a local plugin

Click “Upgrade Moodle database now”. After we should be presented with a success screen. Click “Continue”. Congratulations to us, we have our new Moodle event listener as a local a plug-in up and running. Before testing this new addition, we may want to purge our cache, just in case. It is not mandatory though. Under the Menu Options, tap on Site Administration followed by Development, then click on “Purge caches”. Great, all done and ready for testing.

Note: In the future, whenever you make a change to the plug-in, make sure you increment the version in version.php. In our case from 20211101 to 20211102. This is so that Moodle can detect the update. And whenever there is an update, you will be prompted to follow the just concluded installation steps.

Step 5. Test the event listener plug-in

Since our plug-in listens to events inside Moodle then calls a related callback function, we can therefore perform tests by triggering a particular event. In my case, when I create a new user, I get the details below printed on the screen.

Again, you can write your callback function for each event to do anything as you wish, not just print on screens.

Well, that was a ride. We can now call ourselves Moodle plug-in developers.

Learning Tools

This learning was made easy by the following tools.

Moodle API documentations. This contains all the guidance needed to help in interacting with the APIs.

Stack overflow. The developer community where I learned how to arrange the folder structure for the plug-in.

Learning Strategy

For readers who may not have used Moodle before, the best way to learn up to this stage is to read the official documentation to learn more about this great tool. Then proceed to install it using this guide. Try changing a few things like the theme, so that you can appreciate the benefits of open-source software. Then you can hack it more by building a plug-in.

Reflective Analysis

This guide focused on creating a local plug-in for Moodle with the main focus on event listeners. I hope it also provided you with knowledge on how to create any other local plug-in inside Moodle. Most importantly, I hope I have been able to bring Moodle to the attention of those who may not have interacted with it before. It is a great tool for learning content management.

Conclusion

This was a step-by-step guide to help you build a Moodle event listener as a local plug-in. I hope it was helpful. In the future we shall look, we shall look into how to create other plug-ins. Thank you for following along.

And also, due to the new normal, using technologies like Moodle will go a long way in making sure learning continues. Therefore check out this article on the relevance of technology in the new normal.