TRANSLATION IN PROGRESS --- Plugin migration from 0.72 to 0.78

Between 0.72's GLPI and 0.78's GLPI a lot of changes were made, as much in the database as the files structure.
Using class's auto-loading simply greatly the plugin's writing.
To update a plugin to the 0.78, some steps a required :

  • Change tables and fields used
  • Change filenames
  • Insert function in class
  • Support function's edit in core
  • New hooks available
  • Changing the dropdown's management



The core gets a lot of changes at the database's level.


Table's namespace of a plugin

object's name table
glpi_plugin_nomduplugin_objects (The name of the object has to be plural)

ex: glpi_plugin_monplugin_profiles

Subobject's name table
glpi_plugin_pluginname_objectssubobjects (The name of the object has to be singular and the subobject one has to be plural)

ex: glpi_plugin_pluginname_profiletypes

Two linked object's name table
glpi_plugin_nomduplugin_objects1_objects2 (The names of the 2 linked objects has to plural)

ex: glpi_plugin_pluginname_profiles_entities

Naming convention of a plugin's pages

Each plugin's table must correspond a object.class (object at singular)

ex: table glpi_plugin_myplugin_profiles => file profile.class

Changes in .class files

Naming convention of a plugin's class : new PluginNameofmypluginProfile(); (name of the class at singular)

The function _construct () only reading table name and the type are no longer necessary.


function plugin_monplugin_get_headings

function plugin_monplugin_headings

Changes of the calling parameters of this 2 functions ($type,$ID,$withtemplate => $item,$withtemplate)

function plugin_monplugin_get_headings($item,$withtemplate) {

   $type = get_class($item);
   if ($type == 'Profile') {

Function plugin_monplugin_headings_actions

Changes of the calling parameters of this function ($type => $item)


function plugin_monplugin_init

Plugin's classnames added in core's generals types

registerPluginType('myplugintype', 'PLUGIN_MYPLUGIN_TYPE', 'PluginMypluginObject',
                      array('classname'              => 'PluginMonpluginObject',
                            'tablename'              => 'glpi_plugin_appliances_appliances',
                            'searchpage'             => 'index.php',

Plugin::registerClass('PluginMypluginProfile, array('classname' => 'PluginMypluginObject',                                         ...

Hooks changes on GLPI's action

$PLUGIN_HOOKS['pre_item_add']['myplugin'] = 'plugin_pre_item_update_myplugin';
$PLUGIN_HOOKS['pre_item_add']['myplugin'] = array('Computer' =>'plugin_pre_item_update_myplugin');
 $PLUGIN_HOOKS['pre_item_delete']['myplugin'] = 'plugin_pre_item_myplugin_delete';

$PLUGIN_HOOKS['pre_item_purge']['myplugin'] = objet => function
$PLUGIN_HOOKS['pre_item_purge']['myplugin'] = objet => array('Class', 'Method')); 

Mandatory methods

- static function getTypeName()
- function canCreate()
- function canView()
- function canDelete()
- function cleanDBonPurge()




New prototype

function defineTabs ($options=array())


New prototype

function showFormHeader ($options=array())

Nouveau Operation :
  • Default transition of form in 2 columns
  • Opening of <form, <div (tabsbody) and <table (tab_cadre_fixe)
  • Hiden fields : entities_id, _no_message_link, template_name et is_template

Advices : To use with showFormButtons


New function (factorization of the code)

function showFormButtons ($options=array())
Operation :
  • Closing of <form, <div et <table
  • Hiden fields : id

can / check

New prototype

function can($ID,$right,&$input=NULL)
function check($ID,$right,&$input=NULL)

The parameter $input, is only required for add, it's waiting for values to add (ofently $_POST) and not only the target entity.


Methods proided by the core (cleanRelationData/cleanRelationTable) clean up the records linked to the tabs during the deleting of a object.
  • glpi_contracts_items (if registered in 'contract_types')
  • glpi_documents_items (doc_types)
  • glpi_infocoms (infocom_types)
  • glpi_networkports et glpi_networkports_networkports (netport_types)
  • glpi_reservationitems (reservation_types)
  • glpi_tickets (helpdesk_types)

It's neither usefull to anticipate in the method cleanDBonPurge of the type, but to ensure of the enrichissement of the tables during the Plugin::registerClass.

Changes of the objects types's name

To check in the define.php (PROFILE_TYPE => 'Profile', COMPUTER_TYPE => 'Computer',.....)

Renamed Classes

Enterprise   =>   Supplier

Session variables

$_SESSION["glpiview_ID"]  =>  $_SESSION["glpiis_ids_visible"] 
$_SESSION['glpiID']       =>  getLoginUserID()

Global variables

Deletings of $INFOFORM_PAGES;

Creation of the global constant DROPDOWN_EMPTY_VALUE to replace the ----- in the dropdowns

$LINK_ID_TABLE[$type] => $item->getTable


$CFG_GLPI["mailing"]                   =>   $CFG_GLPI["use_mailing"]
 $CFG_GLPI["deleted_tables"]           =>   $item->maybeDeleted()
 $CFG_GLPI["template_tables"]          =>   $item->maybeTemplate()
 $CFG_GLPI["specif_entities_tables"]   =>   $item->isEntityAssign()
 $CFG_GLPI["dropdowntree_tables"]      =>   $item instanceof CommonTreeDropdown 
 $CFG_GLPI["devices_tables"]           =>                                 
 $CFG_GLPI["recursive_type"]           =>   $item->maybeRecursive()

Deleted function

alphabetical order :

Older function Alternative
addDeviceDocument() Document_Item->add(...)
addDeviceContract() Contract_Item->add(...)
addDropdown() Dropdown::import(...)
dropdownAllItems() Dropdown::showAllItems(...)
dropdownArrayValues[ReadOnly]() Dropdown::showFromArray(...)
dropdownConnectPort() NetworkPort::dropdownConnect(...)
dropdownHours() Dropdown::showHours(...)
dropdownInteger() Dropdown::showInteger(...)
dropdownLanguages() Dropdown::showLanguages(...)
dropdownNoneReadWrite() Profile::dropdownNoneReadWrite(...)
dropdownNoValue() Dropdown::show(...)
dropdownPlanningState() Planning::dropdownState(...)
dropdownRequestType(...) Dropdown::show('RequestType', ...)
dropdownRules() Rule::dropdown()
dropdownValue() Dropdown::show(...)
dropdownyesno() Dropdown::showYesNo(...)
externalImportDropdown() Dropdowwn::importExternal(...)
getAllDropdown() Dropdown::getStandardDropdownItemTypes()
getContractSuppliers() Contract->getSuppliersNames()
getDocumentLink() Document->getDownloadLink(...)
getDropdownName() Dropdown::getDropdownName(...)
getPlanningState() Planning::getState(...)
getRequestTypeName(...) Dropdown::getDropdownName('glpi_requesttypes',...)
getYesNo() Dropdown::getYesNo(...)
globalManagementDropdown() Dropdown::showGlobalSwitch(...)
haveTypeRight($type,'r') $item = new $type(); $item->canGlobal('r')
haveTypeRight($itemtype,'r') $item = new $itemtype(); $item->canView('r')
privatepublicSwitch() Dropdown::showPrivatePublicSwitch(...)
registerPluginType() Plugin::registerClass(...)
showContractAssociated() Contract::showAssociated(...)
showDocumentAssociated() Document::showAssociated(...)
showInfocomForm() Infocom::showForItem(...)
showSaveBookmarkButton() Bookmark::showSaveButton(...)
useplugin Plugin::load(...)


This new method has to return the research's options of the current type.

Using Mbstring to handle UTF8

substr        =>   utf8_substr
utf8_decode   =>   decodeFromUtf8
utf8_encode   =>   encodeFromUtf8
strtolower    =>   utf8_strtolower
strtoupper    =>   utf8_strtoupper

Deleted HOOK
  • plugin_example_getAddSearchOption() : replaced by the method getSearchOptions of the type and the hook plugin_example_getAddSearchOptions

Added HOOK

  • plugin_example_getAddSearchOptions($itemtype) returns the research options added by the plugin to the existing types
  • 0.78.2 : plugin_example_searchOptionsValues($params = array()) allows to reasearch on the engine whith a particular dropdown (intern at the plugin)
  • 0.78.2 : plugin_example_displayConfigItem($type,$ID,$data,$num) Allows to personalise the style of the <td> in the objects list
  • 0.78.3 : 'post_init' : Allows to realise treatment after the init of the others plugins

Task scheduler

The hook 'cron' is no longer used

During the installation a plugin can registrer a taslk by using

   CronTask::Register('pluginame', 'taskname', DAY_TIMESTAMP, array('param'=>50));

Deleting is automatically done by the core during the uninstall of the plugin.

It should then profite 1 function

function plugin_example_cron_info($name)

Which returns a table with 2 entrances for the table $name including 'description' (description localised of the task) and 'parameter' (optional, localised description of the parameter)

And for each taslk, a execute function

function plugin_example_cron_sample_run($task)

The object $task allows to record events ($task->log) and statistics ($task->add/setVolume)
The return code has to be : 0 (nothing to do), >0 (done) or <0 (to be continued)