OpenCart 2.0.x Event System Tutorial

Overview

OpenCart 2.x introduces a number of new features for the module developers and one of them is the event system. This is going to be a quick tutorial teaching you how to make use of it in your modules.

The concept is simple, yet very effective. It allows you to write code which will get executed when something interesting happens in OpenCart. Like when an order is made, or a customer is created without the need of using vQmod or OCMOD. By using the events system, you can avoid collisions which happen when you are using a modification system like vQmod or OCMOD. Additionally since you write the event handlers in PHP file, you get to enjoy proper code coloring/completion/linting from your editor/IDE.

The Basics

Making a real use of events involves only two steps:

  1. Register an event handler

  2. Implement the event handler

The event handlers are simply methods defined in controller files. You can use one file for all your methods or you can create separate controller for your event handlers. To register your event handlers you need to use the extension/event model (OpenCart 2.0.1+) or the tool/event model for OpenCart 2.0.0.0. The extension/event model has 2 methods: addEvent($code, $trigger, $action) and deleteEvent($code). As you can guess the addEvent() method is used to register event handlers and the deleteEvent() is used to unregister event handlers. It is a good practice to register your event handlers in the install() method of your module’s controller in the admin/ directory. It is also advised to unregister your event handlers when your module is being uninstalled, which can be done in the uninstall() method of the same controller file.

The $code argument is used to group your event handlers. It is a good idea to set this to the name of your module, much like you have named your main controller file.

The $trigger argument is the event name which you would like to set your handler to. A list of all available triggers can be found here: https://github.com/opencart/opencart/wiki/Events-(script-notifications).

The $action argument is the route to your handler function. It is written in the form of a standard route to a controller. For example module/mymodule/on_user_created.

Example

We know that an example is worth a lot, so we will walk you through the steps of implementing an event handler with simple code examples. The example assumes that we are working with OpenCart 2.0.1+. Now let’s assume that we are creating a module called “My Module”. The admin controller file for the module will be admin/controller/module/mymodule.php. The catalog controller file for the module will be catalog/controller/module/mymodule.php.

The module will achieve 2 simple tasks - send e-mail messages to the administrator when a store is deleted and upon a customer registration. The triggers that we are going to use are pre.admin.store.delete and post.customer.add.

First we will register our event handlers in the install() method of our module:

public function install() {
    $this->load->model('extension/event');
    $this->model_extension_event->addEvent('mymodule', 'pre.admin.store.delete', 'module/mymodule/on_store_delete');
    $this->model_extension_event->addEvent('mymodule', 'post.customer.add', 'module/mymodule/on_customer_add');
}

We should also take care of the uninstall process like this:

public function uninstall() {
    $this->load->model('extension/event');
    $this->model_extension_event->deleteEvent('mymodule');
}

Next, we need to implement the event handlers. The pre.admin.store.delete event is emitted in the admin area, so its handler must be implemented in the admin controller file for our module. We would like our event handler method to notify the administrator that a store has been deleted. Events starting with pre are emitted before the action is executed, and events starting with post are executed after the action has been taken. We would also like to include the store domain in our message, which is why we have chosen the “pre” event instead of the “post”. If we register for the post.admin.store.delete event, we will not be able to read the store’s domain.

Our event handler should look something like this:

public function on_store_delete($store_id) {
    $this->load->model('setting/store');
    $store_info = $this->model_setting_store->getStore($store_id);
    $admin_mail = $this->config->get('config_email');
    mail($admin_mail, "A store has been deleted", "The store " . $store_info['url'] . " was deleted.");
}

All that is left now is to implement the handler method for the post.customer.add event. We will do this in the catalog controller of our module. The method will notify the administrator when a new customer is registered. The method should look similar to this:

public function on_customer_add($customer_id) {
    $this->load->model('account/customer');
    $customer_info = $this->model_account_customer->getCustomer($customer_id);
    $admin_mail = $this->config->get('config_email');
    mail($admin_mail, "New Customer", "A new customer has just registered with the following e-mail: " . $customer_info['email']);
}

Note: We are using the mail() function for sending e-mails for simplicity. In a real module you need to use OpenCart’s Mail class for sending e-mails.

That’s it! Our module is ready to rock. The final versions of our files is as follows:

admin/controller/module/mymodule.php

<?php
class ControllerModuleMyModule extends Controller {
    public function install() {
        $this->load->model('extension/event');
        $this->model_extension_event->addEvent('mymodule', 'pre.admin.store.delete', 'module/mymodule/on_store_delete');
        $this->model_extension_event->addEvent('mymodule', 'post.customer.add', 'module/mymodule/on_customer_add');
    }
    
    public function uninstall() {
        $this->load->model('extension/event');
        $this->model_extension_event->deleteEvent('mymodule');
    }
    
    public function on_store_delete($store_id) {
        $this->load->model('setting/store');
        $store_info = $this->model_setting_store->getStore($store_id);
        $admin_mail = $this->config->get('config_email');
        mail($admin_mail, "A store has been deleted", "The store " . $store_info['url'] . " was deleted.");
    }
}

catalog/controller/module/mymodule.php

<?php
class ControllerModuleMyModule extends Controller {
    public function on_customer_add($customer_id) {
        $this->load->model('account/customer');
        $customer_info = $this->model_account_customer->getCustomer($customer_id);
        $admin_mail = $this->config->get('config_email');
        mail($admin_mail, "New Customer", "A new customer has just registered with the following e-mail: " . $customer_info['email']);
    }
}

Advanced

Apart from the standard use, the event system can be used to create cross-module integrations. Using the Event object ($this->event), you can trigger any event at any point. You can use it to trigger your own events as well. Imagine that you are developing a module for customer comments. You can trigger events on a comment post, for example. This will allow other module developers to create handler methods for your events and execute code without the need of vQmod or OCMOD. This will ensure better system stability and better customer experience. You can also use the system to register and trigger your own events at runtime.

The Event class is defined in the system/engine/event.php file, so you can take a look at it for further reference.

Conclusion

Mastering the events in OpenCart is beneficial in many ways, both for the developers and the customers. When possible you should always opt for the events instead of a modification system like vQmod and OCMOD. It is less likely that your extensions will collide with the other developers' extensions which leads to better customer experience and less work for you to fix collisions. It also allows for inter-module communication, so you can make several modules working together nicely and elegantly.

 

Join 11,000+ subscribers receiving actionable E-commerce advice

* Unsubscribe any time
comments powered by Disqus