OSTicket Plugin Development, Part 3

Back to parts 1 and 2

Part 3.  Plugin Class

This is the meat and potatoes of your plugin.  In this class you should define all initialization information for your plugin and bootstrap any other files that you may have.  If you recall, in Part 1, we defined our plugin file and class as

'plugin'='equipment.php:EquipmentPlugin'

.

So we need create a new file named equipment.php and define new class within that file EquipmentPlugin.  EquipmentPlugin must extend Plugin class which is defined in <INSTALL_ROOT>/include/class.plugin.php file.

So equipment plugin file looks like this:

<link rel="stylesheet" href="../assets/default/css/theme_equipment.css" media="screen">
<?php

require_once(INCLUDE_DIR . 'class.plugin.php');
require_once(INCLUDE_DIR . 'class.signal.php');
require_once(INCLUDE_DIR . 'class.app.php');

require_once('config.php');

define('EQUIPMENT_TABLE',TABLE_PREFIX.'equipment');
define('EQUIPMENT_CATEGORY_TABLE',TABLE_PREFIX.'equipment_category');
define('EQUIPMENT_STATUS_TABLE',TABLE_PREFIX.'equipment_status');
define('EQUIPMENT_TICKET_TABLE',TABLE_PREFIX.'equipment_ticket');
define('PLUGINS_ROOT',INCLUDE_DIR.'plugins/');
define('EQUIPMENT_PLUGIN_ROOT',PLUGINS_ROOT.'equipment/');
define('EQUIPMENT_INCLUDE_DIR',EQUIPMENT_PLUGIN_ROOT.'include/');
define('EQUIPMENT_STAFFINC_DIR',EQUIPMENT_INCLUDE_DIR.'staff/');
define('EQUIPMENT_CLIENTINC_DIR',EQUIPMENT_INCLUDE_DIR.'client/');

require_once(EQUIPMENT_INCLUDE_DIR . 'class.equipment_install.php');

class EquipmentPlugin extends Plugin {

    var $config_class = 'EquipmentConfig';

    function bootstrap() {
        if ($this->firstRun()) {
            $this->configureFirstRun();
        }

        $config = $this->getConfig();

        if ($config->get('equipment_backend_enable')) {
            $this->createStaffMenu();

            if ($config->get('equipment_frontend_enable')) {
                $this->createFrontMenu();
            }
        }
      //  Signal::connect('model.updated', array('EquipmentPlugin', 'callback'));
    }

    /**
     * Creates menu links in the staff backend.
     */
    function createStaffMenu() {

        Application::registerStaffApp('Equipment',
                'equipment.php',
                array(iconclass => 'equipment'));
        Application::registerStaffApp('Equipment Categories',
                'equipment_categories.php',
                array(iconclass => 'faq-categories'));
        Application::registerStaffApp('Equipment Status',
                'equipment_status.php',
                array(iconclass => 'equipment_status'));
    }

    /**
     * Creates menu link in the client frontend.
     * Useless as of OSTicket version 1.9.2.
     */
    function createFrontMenu() {
        Application::registerClientApp('Equipment Status',
                'equipment_front/index.php',
                array(iconclass => 'equipment'));
    }

    /**
     * Checks if this is the first run of our plugin.
     * @return boolean
     */
    function firstRun() {
        $sql='SHOW TABLES LIKE \''.EQUIPMENT_TABLE.'\'';
        $res=db_query($sql);
        return  (db_num_rows($res)==0);
    }

    /**
     * Necessary functionality to configure first run of the application
     */
    function configureFirstRun() {
       if(!$this->createDBTables())
       {
           echo "First run configuration error.  "
            . "Unable to create database tables!";
       }
    }

    /**
     * Kicks off database installation scripts
     * @return boolean
     */
    function createDBTables() {
       $installer = new EquipmentInstaller();
       return $installer->install();

    }

    /**
     * Uninstall hook.
     * @param type $errors
     * @return boolean
     */
    function pre_uninstall(&$errors) {
       $installer = new EquipmentInstaller();
       return $installer->remove();
    }

}

Let’s break it down line by line:

<link rel="stylesheet" href="../assets/default/css/theme_equipment.css" media="screen">

OSTicket doesn’t have any functionality to include your custom CSS files, so we have to do it here before any code. (GitHub Issue 1074).

require_once(INCLUDE_DIR . 'class.plugin.php');

We inherit from Plugin class defined there.

require_once(INCLUDE_DIR . 'class.signal.php');

This class provides functionality for wiring into system generated signals.  More information on this class in the following post.

require_once(INCLUDE_DIR . 'class.app.php');

This class lets us create customized menu items in the Admin, Staff and User areas.

require_once('config.php');

This is our configuration class, we need to know what options have been selected by user.

define('EQUIPMENT_TABLE',TABLE_PREFIX.'equipment');
define('EQUIPMENT_CATEGORY_TABLE',TABLE_PREFIX.'equipment_category');
define('EQUIPMENT_STATUS_TABLE',TABLE_PREFIX.'equipment_status');
define('EQUIPMENT_TICKET_TABLE',TABLE_PREFIX.'equipment_ticket');
define('PLUGINS_ROOT',INCLUDE_DIR.'plugins/');
define('EQUIPMENT_PLUGIN_ROOT',PLUGINS_ROOT.'equipment/');
define('EQUIPMENT_INCLUDE_DIR',EQUIPMENT_PLUGIN_ROOT.'include/');
define('EQUIPMENT_STAFFINC_DIR',EQUIPMENT_INCLUDE_DIR.'staff/');
define('EQUIPMENT_CLIENTINC_DIR',EQUIPMENT_INCLUDE_DIR.'client/');

This is where we define our custom paths and variables.

require_once(EQUIPMENT_INCLUDE_DIR . 'class.equipment_install.php');

This our plugin installer class.  More on that below.

class EquipmentPlugin extends Plugin {

Class definition.

 function bootstrap() {

This function will be called by OSTicket when it initializes our plugin.  It is called every time user accesses OSTicket.  Our initialization code shall go here.

 if ($this->firstRun()) {
            $this->configureFirstRun();
        }

There is no post-install hook provided by OSTicket (Issue 1069).  This is a work around.  Here we check if this plugin is being activated for the first time, if it is, we call our initial configuration function.

$config = $this->getConfig();

Plugin configuration is loaded here.

        if ($config->get('equipment_backend_enable')) {
            $this->createStaffMenu();

Here we check if user enabled our plugin in the back end.  If it is enabled, we call a function to create a menu for Staff panel, this function is defined later in the file.

 if ($config->get('equipment_frontend_enable')) {
                $this->createFrontMenu();
            }

Here we check if user enabled our plugin in the front end.  If it is enabled, we call a function to create a menu for User panel, this function is defined later in the file.

function createStaffMenu() {

        Application::registerStaffApp('Equipment',
                'equipment.php',
                array(iconclass => 'equipment'));
        Application::registerStaffApp('Equipment Categories',
                'equipment_categories.php',
                array(iconclass => 'faq-categories'));
        Application::registerStaffApp('Equipment Status',
                'equipment_status.php',
                array(iconclass => 'equipment_status'));
    }

This function creates menu entries in the Staff panel.  It calls static function registerStaffApp of the Application class.  The function parameters are:

  1. Menu item name
  2. URL of the menu item target.
  3. Some undocumented array.  Only option that is known is iconclass – style sheet class name for the menu item icon.
function createFrontMenu() {
        Application::registerClientApp('Equipment Status',
                'equipment_front/index.php',
                array(iconclass => 'equipment'));
    }

This function creates menu entries in the Front User panel.  It calls static function registerClientApp of the Application class.  The function parameters are:

  1. Menu item name
  2. URL of the menu item target.
  3. Some undocumented array.  Only option that is known is iconclass – style sheet class name for the menu item icon.

Actually Front User menu items will not show up due to the Issue 1070.

 function firstRun() {
        $sql='SHOW TABLES LIKE \''.EQUIPMENT_TABLE.'\'';
        $res=db_query($sql);
        return  (db_num_rows($res)==0);
    }

    /**
     * Necessary functionality to configure first run of the application
     */
    function configureFirstRun() {
       if(!$this->createDBTables())
       {
           echo "First run configuration error.  "
            . "Unable to create database tables!";
       }
    }

    /**
     * Kicks off database installation scripts
     * @return boolean
     */
    function createDBTables() {
       $installer = new EquipmentInstaller();
       return $installer->install();

    }

These three functions perform basic checks to see if our database tables have been installed.  If they are missing, it is assumed to be an initial run and they are created.

function pre_uninstall(&$errors) {
       $installer = new EquipmentInstaller();
       return $installer->remove();
    }

This is an uninstall hook.  It is called when plugin is being removed.

****

This is basically all you need to start with a plugin.  Read on for more information on other features.

To Part 4, Staff Panel Links->