Developer Area/Events API

From Mahara Wiki
Jump to: navigation, search

Mahara has a simple Event Subscription API that lets plugins respond to actions performed throughout the system. When hookable events happen in core code, the code triggers an "event". Plugins can "subscribe" to these events, providing an "event handler" function that will be called when an event is triggered.

It's a simple version of the Publish-subscribe pattern.

Subscribing to an Event

To subscribe your Plugin to an event type, override the public static function "get_event_subscription()" in your Plugin subclass. Your function should return an array of event subscription objects. Each event subscription object should be a generic object containing three fields:

  • plugin: The name of the plugin
  • event: The name of the event you want to subscribe to
  • callfunction: The (public static) function in the plugin's Plugin subclass, which should be called when the event occurs.

Example:

The blog core plugin subscribes to the createuser event, in order to create a default Journal for each newly created user. Here's what the subscription-related code looks like in artefact/blog/lib.php:

class PluginArtefactBlog extends PluginArtefact { 

    public static function get_event_subscriptions() {
        $sub = new stdClass();
        $sub->plugin = 'blog';
        $sub->event = 'createuser';
        $sub->callfunction = 'create_default_blog';
        return array($sub);
    }

    public static function create_default_blog($event, $user) {
        $name = display_name($user, null, true);
        $blog = new ArtefactTypeBlog(0, (object) array(
            'title'       => get_string('defaultblogtitle', 'artefact.blog', $name),
            'owner'       => $user['id'],
        ));
        $blog->commit();
    }
}

In core code

Core event subscriptions are inserted directly into the event_subscription table, by the core_install_firstcoredata_defaults() function in htdocs/lib/upgrade.php (on installation), and by the xmldb_core_upgrade() function in htdocs/lib/db/upgrade.php (on upgrade)

Triggering an event

Triggering an event is easy. You simply call:

handle_event(
    $eventtype,
    $data
);
  • $eventtype is a string with the name of the event type
  • $data is an object containing data that subscribers to the event type will want

It's up to the author of each new event type to decide what data should be passed to that event's subscribers. Unfortunately Mahara currently has no central place to document this data. Your best bet is simply to search the source code for the name of the event type, and see what the callers are passing in.

Supported event types

The legal 24 event types are stored in the database table event_type. As of Mahara 1.10, the following event types are supported:

  • activateuser
  • addfriend
  • addfriendrequest
  • blockinstancecommit
  • creategroup
  • createuser
  • deactivateuser
  • deleteartefact
  • deleteartefacts
  • deleteblockinstance
  • deleteuser
  • deleteview
  • expireuser
  • loginas
  • removefriend
  • removefriendrequest
  • saveartefact
  • saveview
  • suspenduser
  • undeleteuser
  • unexpireuser
  • unsuspenduser
  • updateuser
  • userjoinsgroup

To play well with existing code, your code should trigger one of these events if it does the related action.

Developing new event types

If you need to provide event subscription functionality, and none of the existing event types are suitable for what you're doing, you can create a new event type.

First, insert a record into the event_type table in the database. This is a simple table with just one column, and each record is the name of a recognized event type. You must insert into this table, because all of the event subscription tables use it as a foreign key. Your new event type should be added to the list in the core_install_firstdata_defaults() function in htdocs/lib/upgrade.php (which will add it to new installations), and you should add a section to htdocs/lib/db/upgrade.php (which will add it for upgraded sites). Or if you're installing an event type as part of a plugin, place this code into your plugin's install and upgrade scripts.

Our current convention on the names of core event types, is that they are all lowercase and alphabetic. If you are creating new event types for a customization or plugin, it's advisable to preface them with a namespace to prevent potential conflicts with new core event types: e.g. "local:killprocess" or "artefact_foo:createfoo".

You'll also need to decide what data will be in the data object sent to the event subscribers. (Or if event subscribers won't need any data at all, the data object can simply be NULL.) And you should document the structure of this data, preferably in the most prominent place in the code where this event gets fired off.