Skip to content
Pierre de Vésian edited this page Jan 19, 2017 · 3 revisions

The use of these functions are defined in advance setup.php : How to setup

Install / uninstall a plugin

// Install process for plugin : need to return true if succeeded
function plugin_example_install() {
   global $DB;
   if (!TableExists("glpi_plugin_example")){
      $query="CREATE TABLE `glpi_plugin_example_examples` (
            `id` INT(11) NOT NULL AUTO_INCREMENT,
            `name` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
            `serial` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
            `plugin_example_dropdowns_id` INT(11) NOT NULL DEFAULT '0',
            `is_deleted` TINYINT(1) NOT NULL DEFAULT '0',
            `is_template` TINYINT(1) NOT NULL DEFAULT '0',
            `template_name` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
            PRIMARY KEY (`id`)
         ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
         ";
      $DB->query($query) or die("error creating glpi_plugin_example ". $DB->error());
      $query="INSERT INTO `glpi_plugin_example` (`id`, `name`, `serial`, `plugin_example_dropdowns_id`, `deleted`, `is_template`, `template_name`) VALUES
         (1, 'example 1', 'serial 1', 1, 0, 0, NULL),
         (2, 'example 2', 'serial 2', 2, 0, 0, NULL),
         (3, 'example 3', 'serial 3', 1, 0, 0, NULL);";
      $DB->query($query) or die("error populate glpi_plugin_example ". $DB->error());

   }
   if (!TableExists("glpi_plugin_example_dropdowns")) {
      $query="CREATE TABLE `glpi_plugin_example_dropdowns` (
               `id` INT(11) NOT NULL AUTO_INCREMENT,
               `name` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
               `comment` TEXT NULL COLLATcreatingE 'utf8_unicode_ci',
               PRIMARY KEY (`id`),
               INDEX `name` (`name`)
            ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";

      $DB->query($query) or die("error creating glpi_plugin_example_dropdowns". $DB->error());
      $query="INSERT INTO `glpi_plugin_example_dropdowns` (`id`, `name`, `comments`) VALUES
         (1, 'dp1', 'comment 1'),
         (2, 'dp2', 'comment 2');";
      $DB->query($query) or die("error populate glpi_plugin_example_dropdowns". $DB->error());

   }
   return true;
}
// Uninstall process for plugin : need to return true if succeeded
function plugin_example_uninstall() {creating
   global $DB;

   if (TableExists("glpi_plugin_example")) {
      $query="DROP TABLE `glpi_plugin_example`;";
      $DB->query($query) or die("error deleting glpi_plugin_example");
   }
   if (TableExists("glpi_plugin_example_dropdowns")) {

      $query="DROP TABLE `glpi_plugin_example_dropdowns`;";
      $DB->query($query) or die("error deleting glpi_plugin_example_dropdowns");
   }
   return true;
}

Rights Management

Example : use core GLPI rights to determine the rights of the plugin. Each plugin can have its own rights management

TODO...

Management Dropdowns

To display your custom dropdowns in Setup > Dropdown, you should specify it :

// Define Dropdown tables to be managed in GLPI :
function plugin_example_getDropdown() {
   // Classname => label
   return array("PluginExampleDropdown"=>"Plugin Example Dropdown");
}

Using the helpdesk

Defines whether you can use the plugin with the helpdesk

function plugin_example_AssignToTicket($types) {
   $types['PluginExampleExample'] = "Example";
   return $types;
}

Hook to pull additional information from the directory

function plugin_retrieve_more_data_from_ldap_example(array $datas) {
   return $datas;
}

The variables $datas contains all information stored in the GLPI user profile.
To add attributes, just add data into $datas.
Return $datas so that the variable is reinjected into GLPI.

function plugin_retrieve_more_field_from_ldap_example($fields) {
   return $fields;
}

Using the search engine

TODO: need review and moving to another file...

You can then set the items displayed in your search by defining the function plugin_<plugin_name>_getSearchOption :

function plugin_example_getSearchOption() {
   global $LANG;
   $sopt=array();

   // header shared
   $sopt[PLUGIN_EXAMPLE_TYPE]['common']="Header Needed";

   $sopt[PLUGIN_EXAMPLE_TYPE][1]['table']='glpi_plugin_example';
   $sopt[PLUGIN_EXAMPLE_TYPE][1]['field']='name';
   $sopt[PLUGIN_EXAMPLE_TYPE][1]['linkfield']='name';
   $sopt[PLUGIN_EXAMPLE_TYPE][1]['name']=$LANG['plugin_example']["name"];
   $sopt[PLUGIN_EXAMPLE_TYPE][1]['datatype']='itemlink';

   $sopt[PLUGIN_EXAMPLE_TYPE][2]['table']='glpi_plugin_example_dropdows';
   $sopt[PLUGIN_EXAMPLE_TYPE][2]['field']='name';
   $sopt[PLUGIN_EXAMPLE_TYPE][2]['linkfield']='FK_dropdown';
   $sopt[PLUGIN_EXAMPLE_TYPE][2]['name']='Dropdown';

   $sopt[PLUGIN_EXAMPLE_TYPE][3]['table']='glpi_plugin_example';
   $sopt[PLUGIN_EXAMPLE_TYPE][3]['field']='serial';
   $sopt[PLUGIN_EXAMPLE_TYPE][3]['linkfield']='serial';
   $sopt[PLUGIN_EXAMPLE_TYPE][3]['name']='Serial';
   $sopt[PLUGIN_EXAMPLE_TYPE][3]['usehaving']=true;
   
   $sopt[PLUGIN_EXAMPLE_TYPE][30]['table']='glpi_plugin_example';
   $sopt[PLUGIN_EXAMPLE_TYPE][30]['field']='ID';
   $sopt[PLUGIN_EXAMPLE_TYPE][30]['linkfield']='';
   $sopt[PLUGIN_EXAMPLE_TYPE][30]['name']=$LANG["common"][2];
   
   // if a table exists to link the type COMPUTER
   $sopt[COMPUTER_TYPE][1002]['table']='glpi_plugin_example';
   $sopt[COMPUTER_TYPE][1002]['field']='name';
   $sopt[COMPUTER_TYPE][1002]['linkfield']='';
   $sopt[COMPUTER_TYPE][1002]['name']="plugin_example";
   $sopt[COMPUTER_TYPE][1002]['forcegroupby']='1';
   $sopt[COMPUTER_TYPE][1002]['datatype']='itemlink';
   $sopt[COMPUTER_TYPE][1002]['itemlink_type']=PLUGIN_EXAMPLE_TYPE;
   return $sopt;
}

Usable Datatypes

  • itemlink
  • text
  • bool
  • email
  • weblink
  • number
  • decimal
  • date
  • datetime
  • date_delay

The search engine then simply calls a PHP page, for example :

$NEEDED_ITEMS=array("search");

define('GLPI_ROOT', '../..'); 
include (GLPI_ROOT . "/inc/includes.php");


checkTypeRight(PLUGIN_EXAMPLE_TYPE,"r");

manageGetValuesInSearch(PLUGIN_EXAMPLE_TYPE);

searchForm(PLUGIN_EXAMPLE_TYPE,$_GET);

showList(PLUGIN_EXAMPLE_TYPE,$_GET);

You can also define special cases of research by defining one or more of the following if necessary (the datatype are automatically managed):

TODO

// See also PluginExampleExample::getSpecificValueToDisplay()
function plugin_example_giveItem($type,$ID,$data,$num) {
   $searchopt = &Search::getOptions($type);
   $table = $searchopt[$ID]["table"];
   $field = $searchopt[$ID]["field"];

   switch ($table.'.'.$field) {
      case "glpi_plugin_example_examples.name" :
         $out = "<a href='".Toolbox::getItemTypeFormURL('PluginExampleExample')."?id=".$data['id']."'>";
         $out .= $data["ITEM_$num"];
         if ($_SESSION["glpiis_ids_visible"] || empty($data["ITEM_$num"])) {
            $out .= " (".$data["id"].")";
         }
         $out .= "</a>";
         return $out;
   }
   return "";
}

function plugin_example_addLeftJoin($type, $ref_table, $new_table, $linkfield) {
   // Example of standard LEFT JOIN  clause but use it ONLY for specific LEFT JOIN
   // No need of the function if you do not have specific cases
   switch ($new_table) {
      case "glpi_plugin_example_dropdowns" :
         return " LEFT JOIN `$new_table` ON (`$ref_table`.`$linkfield` = `$new_table`.`id`) ";
   }
   return "";
}

function plugin_example_forceGroupBy($type) {
   switch ($type) {
      case 'PluginExampleExample' :
         // Force add GROUP BY IN REQUEST
         return true;
   }
   return false;
}

function plugin_example_addWhere($link, $nott, $type, $ID, $val, $searchtype) {
   $searchopt = &Search::getOptions($type);
   $table     = $searchopt[$ID]["table"];
   $field     = $searchopt[$ID]["field"];

   $SEARCH = Search::makeTextSearch($val,$nott);

   // Example of standard Where clause but use it ONLY for specific Where
   // No need of the function if you do not have specific cases
    switch ($table.".".$field) {
         case "glpi_plugin_example_examples.serial" :
            return $link." `$table`.`$field` = '$val' ";
    }
   return "";
}

// This is not a real example because the use of Having condition in this case is not suitable
function plugin_example_addHaving($link, $nott, $type, $ID, $val, $num) {
   $searchopt = &Search::getOptions($type);
   $table     = $searchopt[$ID]["table"];
   $field     = $searchopt[$ID]["field"];

   $SEARCH = Search::makeTextSearch($val,$nott);

   // Example of standard Having clause but use it ONLY for specific Having
   // No need of the function if you do not have specific cases
   switch ($table.".".$field) {
      case "glpi_plugin_example.serial" :
         $ADD = "";
         if (($nott && $val!="NULL")
             || $val == '^$') {
            $ADD = " OR ITEM_$num IS NULL";
         }
         return " $LINK ( ITEM_".$num.$SEARCH." $ADD ) ";
   }
   return "";
}

function plugin_example_addSelect($type,$ID,$num) {
   $searchopt = &Search::getOptions($type);
   $table     = $searchopt[$ID]["table"];
   $field     = $searchopt[$ID]["field"];

// Example of standard Select clause but use it ONLY for specific Select
// No need of the function if you do not have specific cases
// switch ($table.".".$field) {
//    case "glpi_plugin_example.name" :
//       return $table.".".$field." AS ITEM_$num, ";
// }
   return "";
}

function plugin_example_addOrderBy($type,$ID,$order,$key=0) {
   $searchopt = &Search::getOptions($type);
   $table     = $searchopt[$ID]["table"];
   $field     = $searchopt[$ID]["field"];

// Example of standard OrderBy clause but use it ONLY for specific order by
// No need of the function if you do not have specific cases
// switch ($table.".".$field) {
//    case "glpi_plugin_example.name" :
//       return " ORDER BY $table.$field $order ";
// }
   return "";
}

Mass Actions

TODO : need review

You can hide fields by defining the function : plugin_<plugin_name>_MassiveActionsFieldsDisplay($type,$table,$field,$linkfield). This function should return TRUE if the element should be displayed, or false to use the default visibility. An example:

// How to display specific update fields ?
// options must contain at least itemtype and options array
function plugin_example_MassiveActionsFieldsDisplay($options=array()) {
   //$type,$table,$field,$linkfield

   $table     = $options['options']['table'];
   $field     = $options['options']['field'];
   $linkfield = $options['options']['linkfield'];

   if ($table == getTableForItemType($options['itemtype'])) {
      // Table fields
      switch ($table.".".$field) {
         case 'glpi_plugin_example_examples.serial' :
            _e("Not really specific - Just for example", 'example');
            //Html::autocompletionTextField($linkfield,$table,$field);
            // Dropdown::showYesNo($linkfield);
            // Need to return true if specific display
            return true;
      }

   } else {
      // Linked Fields
      switch ($table.".".$field) {
         case "glpi_plugin_example_dropdowns.name" :
            _e("Not really specific - Just for example", 'example');
            // Need to return true if specific display
            return true;
      }
   }
   // Need to return false on non display item
   return false;
}

You can also define new actions for mass changes by defining the following functions :

// Define actions :
function plugin_example_MassiveActions($type) {
   switch ($type) {
      // New action for core and other plugin types : name = plugin_PLUGINNAME_actionname
      case 'Computer' :
         return array('PluginExampleExample'.MassiveAction::CLASS_ACTION_SEPARATOR.'DoIt' => __("plugin_example_DoIt", 'example'));

      // Actions for types provided by the plugin are included inside the classes
   }
   return array();
}

TODO : need to add from example class

  • showMassiveActionsSubForm
  • processMassiveActionsForOneItemtype

Actions for core GLPI objects

These functions use the following prototype ($parm containing 2 fields, "type" and "ID", which define the type and ID of the element of the element on which the action should perform.

Todo need compelte review

Actions for moving objects

// Hook done on restore item case
function plugin_item_transfer_example($parm) {
   //TRANS: %1$s is the source type, %2$d is the source ID, %3$d is the destination ID
   Session::addMessageAfterRedirect(sprintf(__('Transfer Computer Hook %1$s %2$d -> %3$d', 'example'), $parm['type'], $parm['id'], $parm['newID']));

   return false;
}

Actions for core GPLI - item headings

TODO : Need complete review (now in class)

Planning

TODO : Need complete review (now in class)

Cron

TODO : Need complete review (now in class)

Custom exports

It is possible to customize the exports by defining the function plugin_<plugin_name>_dynamicReport($parm). $parm as the parameters passed in from $_GET (function printPager).

// Do special actions for dynamic report
function plugin_example_dynamicReport($parm) {
   if ($parm["item_type"] == 'PluginExampleExample') {
      // Do all what you want for export depending on $parm
      echo "Personalized export for type ".$parm["display_type"];
      echo 'with additional datas : <br>';
      echo "Single data : add1 <br>";
      print $parm['add1'].'<br>';
      echo "Array data : add2 <br>";
      Html::printCleanArray($parm['add2']);
      // Return true if personalized display is done
      return true;
   }
   // Return false if no specific display is done, then use standard display
   return false;
}

Additional data can be exported by defining the function : plugin_<plugin_name>_addParamFordynamicReport. The search parameters are accessible via session variables

// Add parameters to Html::printPager in search system
function plugin_example_addParamFordynamicReport($itemtype) {
   if ($itemtype == 'PluginExampleExample') {
      // Return array data containing all params to add : may be single data or array data
      // Search config are available from session variable
      return array('add1' => $_SESSION['glpisearch'][$itemtype]['order'],
                   'add2' => array('tutu' => 'Second Add',
                                   'Other Data'));
   }
   // Return false or a non array data if not needed
   return false;
}