This space is archived

For current information please use the current ExamSys documentation

Writing a SMS plugin

This article explains the basic steps required to create a SMS plugin for your student management system. Please see https://rogo-eassessment-docs.atlassian.net/wiki/spaces/ROGO/pages/26869764 for a list of known plugins.

Simply put a SMS plugin needs to implement the functions in the abstract class plugins_sms which in turn implements the abstract class plugins.

It is recommended (to save having to make changes to your plugin due to core changes) to use the API when enrolling students onto modules, creating modules etc.

 

The repository of the example SMS plugin described in the following article can be found here. It include a dummy web service.

Directory Structure

A SMS plugin should follow the structure:

plugin_example_sms/

admin

classes

cron

db

lang

 

  • The base directory contains

    • readme.MD

      • a markdown file containing information on the plugin and how to install it

        Title: plugin_example_sms Author: Dr Joseph Baxter <joseph.baxter@nottingham.ac.uk> Copyright: University of Nottingham 2021 onwards Description: plugin_example_sms was developed for the University of Nottingham. It is an example SMS plugin for Rogō to show the basics needed to connect to a student management system. Installation: 1. Extract plugin_example_sms archive into the plugins/SMS directory inside Rogō. 2. Install via the plugins/index.php admin screen.
    • version.php

      • a php file containing the version of the plugin and the minimum version of Rogo required for it to work correctly

        $this->version = '1.0.0'; $this->requires = '7.2.3';
  • The admin sub directory contains

    • the php files referenced in plugin class that are called by the Rogo UI when syncing with the SMS manually

  • The classes sub directory contains

    • the main class for the plugin

      • the class name matching the base directory name i.e. plugin_example_sms.class.php

  • The cron sub directory contains

    • the php files used to sync with the SMS via a scheduled cron job

  • The db sub directory contains

    • insert.sql

      • the script called on installation to setup the plugin settings.

    • update.x.x.x.sql

      • update scripts for additional settings

      • x.x.x matching the version of the plugin

  • The lang sub directory contains

    • sub directories for each suppored lang. ‘en’ as a minimum

    • each sub directory contains plugin_example_sms.lang.php file

      • this populates the $string array with plugin translations

The Code

The following snippets are from example main class file that implements all of the required functions for a SMS plugin.

Not all SMS functions are implemented in this example to keep it small. And indeed you may not need to implement all functions. We focus on enrolments as this the most likely functionality you will require.

Get Enrolments

This function is called wither by the plugins scheduled enrolment cron task or manually via the module details admin screen where module enrolments can by sync for this (and next) academic year.

/** * Get enrolments for academic session * @params integer $session academic session to sync enrolments with * @params integer $externalid external system module id */ public function get_enrolments($session = null, $externalid = null) { // Check enabled. if (!$this->is_enabled() or !$this->is_configured('enrolment')) { return; } // Specific module. if (!empty($externalid)) { $args['externalid'] = $externalid; } // Set session if not provided. if (empty($session)) { $yearutils = new \yearutils($this->config->db); $session = $yearutils->get_current_session(); } $args = array('academic_session' => $session); $response = $this->callws($args); // 1. Parse response. $enrol = json_decode($response); // 2. Process enrolments with \api\modulemanagement $mm = new \api\modulemanagement($this->db); $smsimports = array(); $node = 1; foreach ($enrol as $enroldetails) { $currentenrols = array(); $details = \module_utils::get_full_details('external', $enroldetails->id, $this->db, plugin_example_sms::SMS); $moduleid = $details['idMod']; $smsimports[$moduleid]['enrolcount'] = 0; $smsimports[$moduleid]['enrolusers'] = ''; $smsimports[$moduleid]['unenrolcount'] = 0; $smsimports[$moduleid]['unenrolusers'] = ''; // Enrol. $params = array(); $params['moduleextid'] = $enroldetails->id; $params['moduleextsys'] = plugin_example_sms::SMS; $params['session'] = $session; foreach ($enroldetails->users as $users) { $currentenrols[$enroldetails->id][] = $users->id; $params['studentid'] = $users->id; $params['attempt'] = 1; $params['nodeid'] = $node; $node++; $response = $mm->enrol($params, $this->userid); if ($response['statuscode'] === 100) { $smsimports[$moduleid]['enrolcount']++; $smsimports[$moduleid]['enrolusers'] .= $users->username . ','; } } // Unenrol. $params = array(); $params['moduleextid'] = $enroldetails->id; $params['moduleextsys'] = plugin_example_sms::SMS; $params['session'] = $session; $membership = \module_utils::get_student_members($session, $moduleid, $this->db); foreach ($membership as $idx => $member) { if (!in_array($member['studentid'], $currentenrols[$enroldetails->id])) { $params['studentid'] = $member['studentid']; $params['nodeid'] = $node; $response = $mm->unenrol($params, $this->userid); $node++; if ($response['statuscode'] === 100) { $smsimports[$moduleid]['unenrolcount']++; $smsimports[$moduleid]['unenrolusers'] .= $member['username'] . ','; } } } // Update SMS import log table. $smsimports[$moduleid]['enrolusers'] = rtrim($smsimports[$moduleid]['enrolusers'], ','); $smsimports[$moduleid]['unenrolusers'] = rtrim($smsimports[$moduleid]['unenrolusers'], ','); if ($smsimports[$moduleid]['unenrolcount'] > 0 or $smsimports[$moduleid]['enrolcount'] > 0) { \module_utils::log_sms_imports( $moduleid, $smsimports[$moduleid]['enrolcount'], $smsimports[$moduleid]['enrolusers'], $smsimports[$moduleid]['unenrolcount'], $smsimports[$moduleid]['unenrolusers'], 'Example', $session, $this->db ); } } }

As can be seen in the code we call the SMS endpoint (callws function), interpret its response and use the Rogo API to enrol/remove students from modules (\api\modulemanagement class). We also update the SMS log.

Update Enrolments

This is a wrapper function that is called when a new module is added to Rogo. In this instance it calls the above get_enrolments function to sync enrolments with the SMS. And it also calls the get_modules function to sycs module information (not implemented in the example, but would be information such as module name).

Support Check

This function checks is moudle imports are supported by the module by checking the url, blurb and tooltip definitions exists. If not supported the option to modules with the SMS is not shown on the Rogo module admin screen.

Similarly the following funcs checks if module enrolments are supported.

Get plugin name

Gets the name of the plugin, which is used to identify modules, courses etc associated with it within Rogo.

Support functions

Whilst not required functions the below support functions may be helpful.

The above functions are using a function to the plugin which checks the functionality is available.

and a private function to check if the functionality is enabled.

Scheduled Tasks

Scripts can be added to the cron directory in the plugin to be called by the system cron. The script should simply call the relevant action i.e for enrolment

The Database

Settings for the plugin are stored in the core config table.

Filter by label

There are no items with the selected labels at this time.