Developing Plugin Modules

From FreeDESK
(Difference between revisions)
Jump to: navigation, search
Line 158: Line 158:
 
}
 
}
 
?>
 
?>
 +
</source>
 +
 +
The filepath, webpath and ID are provided by the system automatically on startup and can then be used within the PIM.
 +
 +
= Example =
 +
 +
The following provides a simple example of a plugin providing some workload reporting. It would be installed as follows:
 +
* Folder: plugins/workload
 +
* Main file: plugins/workload/workload.php
 +
* Main class: plugins/workload/workload.php::workload
 +
 +
<source lang="php">
 +
 +
<?php
 +
/* -------------------------------------------------------------
 +
This file is part of FreeDESK
 +
 +
FreeDESK is (C) Copyright 2012 David Cutting
 +
 +
FreeDESK is free software: you can redistribute it and/or modify
 +
it under the terms of the GNU General Public License as published by
 +
the Free Software Foundation, either version 3 of the License, or
 +
(at your option) any later version.
 +
 +
FreeDESK is distributed in the hope that it will be useful,
 +
but WITHOUT ANY WARRANTY; without even the implied warranty of
 +
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +
GNU General Public License for more details.
 +
 +
You should have received a copy of the GNU General Public License
 +
along with FreeDESK.  If not, see www.gnu.org/licenses
 +
 +
For more information see www.purplepixie.org/freedesk/
 +
-------------------------------------------------------------- */
 +
 +
// A new class for the PIM extending FreeDESK_PIM,
 +
// named the same as the directory and filename
 +
class workload extends FreeDESK_PIM
 +
{
 +
// The startup method - register functionalityh
 +
function Start()
 +
{
 +
  // Register ourselves as a plugin
 +
  $this->DESK->PluginManager->Register(new Plugin(
 +
    "Workload", "0.01", "Reporting" ));
 +
  // Register a page which will be displayed
 +
  $this->DESK->PluginManager->RegisterPIMPage("workload_page",
 +
    $this->ID);
 +
  // Register an API call for details
 +
  $this->DESK->PluginManager->RegisterPIMAPI("workload_api",
 +
    $this->ID);
 +
  // Add a permission for this action
 +
  $this->DESK->PermissionManager->Register("workload", false);
 +
  // Register a JS script (workload.js) in our directory for inclusion
 +
  // Note the file can be called anything we like or even not in the
 +
  // directory (unlike this PHP file)
 +
  $jspath = $this->webpath . "workload.js";
 +
  $this->DESK->PluginManager->RegisterScript($jspath);
 +
  // Register a CSS file (workload.css)
 +
  $csspath = $this->webpath . "workload.css";
 +
  $this->DESK->PluginManager->RegisterCSS($csspath);
 +
}
 +
// The method to add menu items
 +
function BuildMenu()
 +
{
 +
  // Check if the permission is allowed or don't show the menu
 +
  if ($this->DESK->ContextManager->Permission("workload"))
 +
  {
 +
    // Check if the reporting menu already exists, add if not
 +
    $currentItems = $this->DESK->ContextManager->MenuItems();
 +
    if (!isset($currentItems['reporting']))
 +
    {
 +
      $repmenu = new MenuItem();
 +
      $repmenu->tag = "reporting";
 +
      $repmenu->display = "Reporting";
 +
      $this->DESK->ContextManager->AddMenuItem
 +
        ("reporting", $repmenu);
 +
    }
 +
 +
    // Built the menu item for this plugin
 +
    $sReport = new MenuItem();
 +
    $sReport->tag="workload";
 +
    $sReport->display="Workload";
 +
    // Set the action for the click
 +
    // (show the page 'workload' registered above)
 +
    $sReport->onclick = "DESK.loadSubpage('workload_page');";
 +
    // Add the menu option to the reporting menu
 +
    $this->DESK->ContextManager->AddMenuItem("reporting",$sReport);
 +
  }
 +
}
 +
// Handle page requests (specifically the workload page)
 +
function Page($page)
 +
{
 +
  if ($page == "workload_page" // page is the workload page
 +
  && // and permission for this page
 +
  $this->DESK->ContextManager->Permission("workload"))
 +
  {
 +
    // Page title
 +
    echo "<h3>Workload</h3>\n";
 +
    // Team and user list
 +
    $teamuser = $this->DESK->RequestManager->TeamUserList();
 +
    // Iterate through this list and display workload info
 +
    echo "<table>\n";
 +
    foreach($teamuser as $teamid => $teamdata)
 +
    {
 +
      // Counter for the team
 +
      $teamcount=0;
 +
      echo "<tr>\n";
 +
      echo "<td>\n";
 +
      echo "<b>".$teamdata['name']."</b>\n";
 +
      echo "</td>\n";
 +
      echo "<td><b>\n";
 +
      // Get the requests assigned to just the team
 +
      $requests = $this->DESK->RequestManager->FetchAssigned($teamid, "");
 +
      $reqcount = sizeof($requests);
 +
      echo $reqcount;
 +
      // Increment team counter
 +
      $teamcount += $reqcount;
 +
      echo "</b></td>";
 +
      // Detail link for the team
 +
      $js="Workload.Detail(".$teamid.",'');";
 +
      echo "<td>\n";
 +
      echo "<a href=\"#\" onclick=\"".$js."\">Detail</a>\n";
 +
      echo "</td>";
 +
      echo "</tr>";
 +
      // Detail row for the team
 +
      echo "<tr><td colspan=\"3\" id=\"detail_".$teamid."_\"></td></tr>\n";
 +
      // Iterate through the users in the team
 +
      foreach($teamdata['items'] as $user => $userdata)
 +
      {
 +
        echo "<tr>\n";
 +
        echo "<td>\n";
 +
        echo $userdata['realname'];
 +
        echo "</td>\n";
 +
        echo "<td>\n";
 +
        // Requests for this user and team
 +
        $requests = $this->DESK->RequestManager->FetchAssigned($teamid, $user);
 +
        $reqcount = sizeof($requests);
 +
        echo $reqcount;
 +
        // Increment team counter
 +
        $teamcount+=$reqcount;
 +
        echo "</td>\n";
 +
        // Detail link for the team and user
 +
        $js="Workload.Detail(".$teamid.",'".$user."');";
 +
        echo "<td>\n";
 +
        echo "<a href=\"#\" onclick=\"".$js."\">Detail</a>\n";
 +
        echo "</td>";
 +
        echo "</tr>\n";
 +
        // Detail row for the user
 +
        echo "<tr><td colspan=\"3\" id=\"detail_".$teamid."_".$user."\"></td></tr>\n";
 +
      }
 +
    // The team total
 +
    echo "<tr><td><b>Total</b></td><td><b>".$teamcount."</b></td></tr>\n";
 +
    // A spacer
 +
    echo "<tr><td colspan=\"3\"><hr class=\"workload\"></td></tr>\n";
 +
    }
 +
    echo "</table>\n";
 +
  }
 +
}
 +
// API Handler
 +
function API($mode)
 +
{
 +
  if ($mode == "workload_api" // Correct API Mode
 +
    && // and permission for workload
 +
    $this->DESK->ContextManager->Permission("workload"))
 +
  {
 +
    // Get the team and user requested
 +
    $teamid = isset($_REQUEST['teamid']) ? $_REQUEST['teamid'] : 0;
 +
    $username = isset($_REQUEST['username']) ? $_REQUEST['username'] : "";
 +
    // Get the assigned requests
 +
    $reqs = $this->DESK->RequestManager->FetchAssigned($teamid,$username);
 +
    // Get the list of priorities
 +
    $pris = $this->DESK->RequestManager->GetPriorityList();
 +
    // Our output array with unknown default
 +
    $out = array(0=>array("name"=>"Unknown","total"=>0));
 +
    // Iterate through the requests
 +
    foreach($reqs as $req)
 +
    {
 +
      // Get the priority
 +
      $pri = $req->Get("priority");
 +
      // Check if exists and add to totals
 +
      if (isset($pris[$pri])) // valid
 +
      {
 +
        if (isset($out[$pri]))
 +
          $out[$pri]['total']++;
 +
        else
 +
          $out[$pri]=array(
 +
            "name"=>$pris[$pri]['priorityname'],
 +
            "total"=>1 );
 +
      }
 +
      else
 +
        $out[0]["total"]++;
 +
    }
 +
    // Build the HTML
 +
    $html = "";
 +
    // For each detail line
 +
    foreach($out as $line)
 +
    {
 +
      $html.=$line["name"].": ".$line["total"]."<br />";
 +
    }
 +
    // Create the XML output
 +
    // XML creation object
 +
    $xml = new xmlCreate();
 +
    // Add a char element with CDATA encoding
 +
    $xml->charElement(
 +
      "data",
 +
      $html,
 +
      0,
 +
      false,
 +
      true );
 +
    // Output the XML with the header
 +
    $xml->echoXML(true);
 +
    // Exit (ensure no other output)
 +
    exit();
 +
  }
 +
}
 +
   
 +
 +
}
 +
?>
 +
</source>
 +
 +
Additionally support Javascript and CSS files are used as follows:
 +
 +
<source lang="javascript">
 +
//The PIM Function
 +
function workloadPIM()
 +
{
 +
  // Last detail items asked for
 +
  var teamid = 0;
 +
  var username = "";
 +
 
 +
  // Get detail for the given team and user
 +
  this.Detail = function(teamid, username)
 +
  {
 +
    // Set last requested items
 +
    this.teamid = teamid;
 +
    this.username = username;
 +
   
 +
    // Create a ServerRequest object
 +
    var sr = new ServerRequest();
 +
    // Build the URL to the API
 +
    var url = "api.php?";
 +
    // Add the mode
 +
    url += "mode=workload_api";
 +
    // And the team and user detail
 +
    url += "&teamid="+teamid+"&username="+username;
 +
    // And the SID from FreeDESK
 +
    url += "&sid="+DESK.sid;
 +
    // Define the callback
 +
    sr.callback = Workload.Callback;
 +
    // Set the URL
 +
    sr.url = url;
 +
    // Set to XML
 +
    sr.xmlrequest = true;
 +
    // Call the API
 +
    sr.Post();
 +
  }
 +
 
 +
  // The callback method (API response)
 +
  this.Callback = function(xml, additional)
 +
  {
 +
    // Check if the API has returned an error
 +
    if (DESK.isError(xml))
 +
    {
 +
      // Display error
 +
      Alerts.add(DESK.getError(xml), 2, 10);
 +
      // Exit
 +
      return;
 +
    } // no error so continue
 +
    // Strip the response from the server
 +
    var data = xml.getElementsByTagName("data")[0]
 +
      .firstChild.nodeValue;
 +
    // Get the element to display it in
 +
    var eleID = 'detail_'
 +
      +Workload.teamid
 +
      +"_"+Workload.username;
 +
    var ele = document.getElementById(eleID);
 +
    // And display the data
 +
    ele.innerHTML = data;
 +
  }
 +
}
 +
// Instantiate the workloadPIM object
 +
var Workload = new workloadPIM();
 
</source>
 
</source>

Revision as of 23:52, 21 August 2012

Plugin modules are the heart of FreeDESK extensibility and are developed in PHP. All plugin modules extend the base class FreeDESK_PIM and provide some defined interfaces.

Plugins can register functionality they provide in the main system, register additional pages and menu options for display, register custom API modes and handle request events.

Plugin Modules (PIMs)

PIMs provide some or all of the functionality listed in the FreeDESK_PIM module. For a plugin to work it must be installed in a named directory within the plugin folder, have a main PHP file of the same name and the main PIM class within that file of the same name.

<?php 
/* -------------------------------------------------------------
This file is part of FreeDESK
 
FreeDESK is (C) Copyright 2012 David Cutting
 
FreeDESK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
FreeDESK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with FreeDESK.  If not, see www.gnu.org/licenses
 
For more information see www.purplepixie.org/freedesk/
-------------------------------------------------------------- */
 
/**
 * FreeDESK_PIM is the abstacr base class for all PIM components
**/
abstract class FreeDESK_PIM
{
	/**
	 * FreeDESK instance
	**/
	protected $DESK = null;
 
	/**
	 * File path for PIM
	**/
	protected $filepath = "";
 
	/**
	 * Web path for PIM
	**/
	protected $webpath = "";
 
	/**
	 * ID for PIM
	**/
	protected $ID = 0;
 
	/**
	 * Main Constructor
	 * @param mixed $freeDESK FreeDESK instance
	 * @param string $filepath Path to plugin directory (filebase)
	 * @param string $webpath Path to plugin directory (webpath)
	 * @param int $id Internal FreeDESK ID for PIM
	**/
	function FreeDESK_PIM(&$freeDESK, $filepath, $webpath, $id)
	{
		$this->DESK = &$freeDESK;
		$this->filepath = $filepath;
		$this->webpath = $webpath;
		$this->ID = $id;
	}
 
	/**
	 * Start (when an instance is started from within the system and is installed - to be overriden
	**/
	function Start()
	{
		//
	}
 
	/**
	 * Install - to be overriden
	**/
	function Install()
	{
		//
	}
 
	/**
	 * Activate - to be overriden
	**/
	function Activate()
	{
		//
	}
 
	/**
	 * De-Activate - to be overriden
	**/
	function Deactivate()
	{
		//
	}
 
	/**
	 * Uninstall - to be overriden
	**/
	function Uninstall()
	{
		//
	}
 
	/**
	 * API Call - to be overriden
	 * @param string $mode API Mode
	**/
	function API($mode)
	{
		//
	}
 
	/**
	 * Event Call - to be overriden
	 * @param string $event Event
	 * @param mixed &$data Event data (dependent on the event)
	**/
	function Event($event, &$data)
	{
		//
	}
 
	/**
	 * Build any menu items needed - to be overriden
	**/
	function BuildMenu()
	{
		//
	}
 
	/**
	 * Page has been called for this plugin - to be overriden
	 * @param string $page Page identifier
	**/
	function Page($page)
	{
		//
	}
 
	/**
	 * Static exec/registration function to list provided interfaces
	 * @param mixed $DESK Reference to current FreeDESK instance
	**/
	static function Exec(&$DESK)
	{
		//
	}
 
}
?>

The filepath, webpath and ID are provided by the system automatically on startup and can then be used within the PIM.

Example

The following provides a simple example of a plugin providing some workload reporting. It would be installed as follows:

  • Folder: plugins/workload
  • Main file: plugins/workload/workload.php
  • Main class: plugins/workload/workload.php::workload
<?php 
/* -------------------------------------------------------------
This file is part of FreeDESK
 
FreeDESK is (C) Copyright 2012 David Cutting
 
FreeDESK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
FreeDESK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with FreeDESK.  If not, see www.gnu.org/licenses
 
For more information see www.purplepixie.org/freedesk/
-------------------------------------------------------------- */
 
// A new class for the PIM extending FreeDESK_PIM,
// named the same as the directory and filename
class workload extends FreeDESK_PIM
{
// The startup method - register functionalityh
function Start()
{
  // Register ourselves as a plugin
  $this->DESK->PluginManager->Register(new Plugin(
    "Workload", "0.01", "Reporting" ));
  // Register a page which will be displayed
  $this->DESK->PluginManager->RegisterPIMPage("workload_page",
    $this->ID);
  // Register an API call for details
  $this->DESK->PluginManager->RegisterPIMAPI("workload_api",
    $this->ID);
  // Add a permission for this action
  $this->DESK->PermissionManager->Register("workload", false);
  // Register a JS script (workload.js) in our directory for inclusion
  // Note the file can be called anything we like or even not in the
  // directory (unlike this PHP file)
  $jspath = $this->webpath . "workload.js";
  $this->DESK->PluginManager->RegisterScript($jspath);
  // Register a CSS file (workload.css)
  $csspath = $this->webpath . "workload.css";
  $this->DESK->PluginManager->RegisterCSS($csspath);
}
// The method to add menu items
function BuildMenu()
{
  // Check if the permission is allowed or don't show the menu
  if ($this->DESK->ContextManager->Permission("workload"))
  {
    // Check if the reporting menu already exists, add if not
    $currentItems = $this->DESK->ContextManager->MenuItems();
    if (!isset($currentItems['reporting']))
    {
      $repmenu = new MenuItem();
      $repmenu->tag = "reporting";
      $repmenu->display = "Reporting";
      $this->DESK->ContextManager->AddMenuItem
        ("reporting", $repmenu);
    }
 
    // Built the menu item for this plugin
    $sReport = new MenuItem();
    $sReport->tag="workload";
    $sReport->display="Workload";
    // Set the action for the click
    // (show the page 'workload' registered above)
    $sReport->onclick = "DESK.loadSubpage('workload_page');";
    // Add the menu option to the reporting menu
    $this->DESK->ContextManager->AddMenuItem("reporting",$sReport);
  }
}
// Handle page requests (specifically the workload page)
function Page($page)
{
  if ($page == "workload_page" // page is the workload page
  	&& // and permission for this page
  	$this->DESK->ContextManager->Permission("workload"))
  {
    // Page title
    echo "<h3>Workload</h3>\n";
    // Team and user list
    $teamuser = $this->DESK->RequestManager->TeamUserList();
    // Iterate through this list and display workload info
    echo "<table>\n";
    foreach($teamuser as $teamid => $teamdata)
    {
      // Counter for the team
      $teamcount=0;
      echo "<tr>\n";
      echo "<td>\n";
      echo "<b>".$teamdata['name']."</b>\n";
      echo "</td>\n";
      echo "<td><b>\n";
      // Get the requests assigned to just the team
      $requests = $this->DESK->RequestManager->FetchAssigned($teamid, "");
      $reqcount = sizeof($requests);
      echo $reqcount;
      // Increment team counter
      $teamcount += $reqcount;
      echo "</b></td>";
      // Detail link for the team
      $js="Workload.Detail(".$teamid.",'');";
      echo "<td>\n";
      echo "<a href=\"#\" onclick=\"".$js."\">Detail</a>\n";
      echo "</td>";
      echo "</tr>";
      // Detail row for the team
      echo "<tr><td colspan=\"3\" id=\"detail_".$teamid."_\"></td></tr>\n";
      // Iterate through the users in the team
      foreach($teamdata['items'] as $user => $userdata)
      {
        echo "<tr>\n";
        echo "<td>\n";
        echo $userdata['realname'];
        echo "</td>\n";
        echo "<td>\n";
        // Requests for this user and team
        $requests = $this->DESK->RequestManager->FetchAssigned($teamid, $user);
        $reqcount = sizeof($requests);
        echo $reqcount;
        // Increment team counter
        $teamcount+=$reqcount;
        echo "</td>\n";
        // Detail link for the team and user
        $js="Workload.Detail(".$teamid.",'".$user."');";
        echo "<td>\n";
        echo "<a href=\"#\" onclick=\"".$js."\">Detail</a>\n";
        echo "</td>";
        echo "</tr>\n";
        // Detail row for the user
        echo "<tr><td colspan=\"3\" id=\"detail_".$teamid."_".$user."\"></td></tr>\n";
      }
    // The team total
    echo "<tr><td><b>Total</b></td><td><b>".$teamcount."</b></td></tr>\n";
    // A spacer
    echo "<tr><td colspan=\"3\"><hr class=\"workload\"></td></tr>\n";
    }
    echo "</table>\n";
  }
}
// API Handler
function API($mode)
{
  if ($mode == "workload_api" // Correct API Mode
    && // and permission for workload
    $this->DESK->ContextManager->Permission("workload"))
  {
    // Get the team and user requested
    $teamid = isset($_REQUEST['teamid']) ? $_REQUEST['teamid'] : 0;
    $username = isset($_REQUEST['username']) ? $_REQUEST['username'] : "";
    // Get the assigned requests
    $reqs = $this->DESK->RequestManager->FetchAssigned($teamid,$username);
    // Get the list of priorities
    $pris = $this->DESK->RequestManager->GetPriorityList();
    // Our output array with unknown default
    $out = array(0=>array("name"=>"Unknown","total"=>0));
    // Iterate through the requests
    foreach($reqs as $req)
    {
      // Get the priority
      $pri = $req->Get("priority");
      // Check if exists and add to totals
      if (isset($pris[$pri])) // valid
      {
        if (isset($out[$pri]))
          $out[$pri]['total']++;
        else
          $out[$pri]=array(
            "name"=>$pris[$pri]['priorityname'],
            "total"=>1 );
      }
      else
        $out[0]["total"]++;
    }
    // Build the HTML
    $html = "";
    // For each detail line
    foreach($out as $line)
    {
      $html.=$line["name"].": ".$line["total"]."<br />";
    }
    // Create the XML output
    // XML creation object
    $xml = new xmlCreate();
    // Add a char element with CDATA encoding
    $xml->charElement(
      "data",
      $html,
      0,
      false,
      true );
    // Output the XML with the header
    $xml->echoXML(true);
    // Exit (ensure no other output)
    exit();
  }
}
 
 
}
?>

Additionally support Javascript and CSS files are used as follows:

//The PIM Function
function workloadPIM()
{
  // Last detail items asked for
  var teamid = 0;
  var username = "";
 
  // Get detail for the given team and user
  this.Detail = function(teamid, username)
  {
    // Set last requested items
    this.teamid = teamid;
    this.username = username;
 
    // Create a ServerRequest object
    var sr = new ServerRequest();
    // Build the URL to the API
    var url = "api.php?";
    // Add the mode
    url += "mode=workload_api";
    // And the team and user detail
    url += "&teamid="+teamid+"&username="+username;
    // And the SID from FreeDESK
    url += "&sid="+DESK.sid;
    // Define the callback
    sr.callback = Workload.Callback;
    // Set the URL
    sr.url = url;
    // Set to XML
    sr.xmlrequest = true;
    // Call the API
    sr.Post();
  }
 
  // The callback method (API response)
  this.Callback = function(xml, additional)
  {
    // Check if the API has returned an error
    if (DESK.isError(xml))
    {
      // Display error
      Alerts.add(DESK.getError(xml), 2, 10);
      // Exit
      return;
    } // no error so continue
    // Strip the response from the server
    var data = xml.getElementsByTagName("data")[0]
      .firstChild.nodeValue;
    // Get the element to display it in
    var eleID = 'detail_'
      +Workload.teamid
      +"_"+Workload.username;
    var ele = document.getElementById(eleID);
    // And display the data
    ele.innerHTML = data;
  }
}
// Instantiate the workloadPIM object
var Workload = new workloadPIM();
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox