Fr Plugin072to078 » History » Version 49

Version 48 (tsmr, 01/20/2011 04:08 PM) → Version 49/67 (tsmr, 01/20/2011 04:36 PM)

h1. Migration d'un plugin de GLPI 0.72 vers 0.78

{{toc}}

Entre la version 0.72 et la version 0.78 de GLPI de nombreux changements ont été implémentés, autant sur la base de données que sur la structure des fichiers. L'utilisation de l'auto-chargement de classes simplifie grandement le codage de plugins.
Pour mettre à jour un plugin en 0.78, plusieurs étapes sont nécessaires :

* Modification des tables et champs utilisés
* Modification des noms de fichiers
* Insertion des fonctions dans les classes
* Prise en charge des modifications de fonctions du cœur
* Nouveaux hooks disponibles
* Modification de la gestion des objets de type dropdown (listes déroulantes)

h2. Database

h3. CleanDB

Le coeur a subi d'importantes modification au niveau base de données :

https://forge.indepnet.net/wiki/glpi/CleanDbStudy

h1. MODIFICATIONS A EFFECTUER DANS LES PLUGINS

h2. Règle de nommage des tables d'un plugin

*Nom de table d'un objet*
glpi_plugin_nomduplugin_objets (le nom de l'objet doit être au pluriel)
> ex: glpi_plugin_monplugin_profiles

*Nom de table d'un sous-objet*
glpi_plugin_nomduplugin_objetsousobjets (le nom de l'objet doit être au singulier et celui du sous-objet au pluriel)
> ex: glpi_plugin_monplugin_profiletypes

*Nom de table de 2 objets liés*
glpi_plugin_nomduplugin_objets1_objets2 (les noms des 2 objets liés doivent être au pluriel)
> ex: glpi_plugin_monplugin_profiles_entities

h2. Règle de nommage des pages d'un plugin

A chaque table du plugin doit correspondre un fichier object.class (objet au singulier)
> ex: table glpi_plugin_monplugin_profiles => fichier profile.class

h2. Hook.php

h3. function plugin_monplugin_get_headings

h3. function plugin_monplugin_headings

Changement des paramètres d'appel de ces 2 fonctions ($type,$ID,$withtemplate => $item,$withtemplate)
<pre>
function plugin_monplugin_get_headings($item,$withtemplate) {

$type = get_class($item);
if ($type == 'Profile') {
</pre>

h3. function plugin_monplugin_headings_actions

Changement des paramètres d'appel de la fonction ($type => $item)

h2. setup.php

h3. function plugin_monplugin_init

Ajout des noms de class du plugin dans les types généraux du coeur

<pre>
registerPluginType('typedemonplugin', 'PLUGIN_MONPLUGIN_TYPE', 'PluginMonpluginObjet',
array('classname' => 'PluginMonpluginObjet',
'tablename' => 'glpi_plugin_appliances_appliances',
'searchpage' => 'index.php',
...
</pre>
devient

<pre>
Plugin::registerClass('PluginMonpluginProfile, array('classname' => 'PluginMonpluginObjet',
...

</pre>

Modification des hooks sur les actions de GLPI
On passe de
<pre>
$PLUGIN_HOOKS['pre_item_add']['monplugin'] = 'plugin_pre_item_adde_monplugin'; &#x27;plugin_pre_item_update_monplugin&#x27;;
</pre>

à

<pre>
$PLUGIN_HOOKS['pre_item_add']['monplugin'] = array('Computer' =>'plugin_pre_item_update_monplugin');
</pre>

Remplacement du
<pre> $PLUGIN_HOOKS['pre_item_delete']['monplugin'] = 'plugin_pre_item_monplugin_delete'; </pre>
par
<pre> $PLUGIN_HOOKS['pre_item_purge']['monplugin'] = array('Profile' => array('PluginMonpluginProfile', 'Nomdemafontion')); </pre>

h1. MODIFICATIONS DU COEUR IMPACTANT LES PLUGINS

h2. CommonDBTM

h3. showFormHeader

Nouveau prototype
<pre>
function showFormHeader ($options=array())
</pre>

Nouveau fonctionnement :
* passage par défaut des form sur 2 colonnes
* ouverture des <form, <div (tabsbody) et <table (tab_cadre_fixe)
* champs cachés : entities_id, _no_message_link, template_name et is_template

Conseil : à utiliser conjointement avec showFormButtons

h3. showFormButtons

Nouvelle fonction (factorisation du code)

<pre>
function showFormButtons ($options=array())
</pre>

Fonctionnement :
* fermeture des <form, <div et <table
* champs cachés : id

h3. can / check

Nouveau prototype

<pre>
function can($ID,$right,&$input=NULL)
function check($ID,$right,&$input=NULL)
</pre>

Le paramètre $input, uniquement requis lors d'un ajout, attend les valeurs à ajouter (souvent le $_POST) et pas uniquement l'entité cible.

h3. cleanDBonPurge

Les méthodes fournies par le coeur (cleanRelationData/cleanRelationTable) nettoient les enregistrements liés des tables lors de la suppression d'un objet.
* 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)

Il n'est donc plus utile de le prévoir dans la méthode *cleanDBonPurge* du type, mais de s'assurer de l'enrichissement des tableaux lors du *Plugin::registerClass*.

h2. Changement du nom des types d'objet

A vérifier dans le define.php (PROFILE_TYPE => 'Profile', COMPUTER_TYPE => 'Computer',.....)

h1. A REVOIR

h4. getSearchOptions

Cette nouvelle méthode doit retourner les options de recherche pour le type courant.

h2. Variables de session

<pre>
$_SESSION["glpiview_ID"] remplacé par $_SESSION["glpiis_ids_visible"]
</pre>

h2. Utilisation Mbstring pour gérer UTF8

<pre>
substr remplacé par utf8_substr
</pre>
<pre>
utf8_decode remplacé par decodeFromUtf8
</pre>
<pre>
utf8_encode remplacé par encodeFromUtf8
</pre>
<pre>
strtolower remplacé par utf8_strtolower
</pre>
<pre>
strtoupper remplacé par utf8_strtoupper
</pre>

h2. Configuration

<pre>
$CFG_GLPI["mailing"] remplacé par $CFG_GLPI["use_mailing"]
</pre>

h2. Fonctions supprimées

Liste alphabétique :

|| *Ancienne fonction* || *Alternative* ||
|| addDeviceDocument() || DocumentItem->add() ||
|| addDeviceContract() || ContractItem->add() ||
|| cleanCache(); || ||
|| dropdownRequestType(...); || dropdownValue('glpi_requesttypes', ...) ||
|| getDocumentLink() || Document->getDownloadLink() ||
|| getRequestTypeName(...) || getDropdownName('glpi_requesttypes',...) ||
|| getContractSuppliers() || Contract->getSuppliersNames() ||
|| registerPluginType() || Plugin::registerClass() ||
|| showContractAssociated() || Contract::showAssociated() ||
|| showDocumentAssociated() || Document::showAssociated() ||
|| showInfocomForm() || Infocom::showForItem() ||
|| showSaveBookmarkButton(...) || Bookmark::showSaveButton(...) ||
|| dropdownNoneReadWrite(...) || Profile::dropdownNoneReadWrite(...) ||
|| getPlanningState(...) || TicketPlanning::getState(...) ||
|| dropdownPlanningState(...) || TicketPlanning::dropdownState(...) ||
|| dropdown(...) || CommoDropdown::dropdown(...) ||
|| dropdownValue(...) || CommonDropdown::dropdownValue(...) ||
|| dropdownNoValue(...) || CommonDropdown::dropdownNoValue(...) ||
|| getDropdownName(...) || CommonDropdown::getDropdownName(...) ||

h2. Classes renommées

<pre>
Enterprise => Supplier
</pre>

h2. HOOK supprimés

* plugin_example_getAddSearchOption() : remplacé par la méthode getSearchOptions du type et le hook plugin_example_getAddSearchOptions

h2. HOOK ajoutés

* plugin_example_getAddSearchOptions($itemtype) retourne les options de recherche ajoutées par le plugin aux types existants
* 0.78.2 : plugin_example_searchOptionsValues($params = array()) permet de faire des recherche sur le moteur avec un drodpdown particulier (interne au plugin)
* 0.78.2 : plugin_example_displayConfigItem($type,$ID,$data,$num) Permet de personnaliser le style du <td> dans la liste des objets

h2. Tâche planifiée

Le hook *'cron'* n'est plus utilisé

Lors de l'installation un plugin peut enregistrer une tâche en utilisant
<pre>
CronTask::Register('pluginame', 'taskname', DAY_TIMESTAMP, array('param'=>50));
</pre>
La suppression est automatiquement réalisée par le coeur lors de la désinstallation du plugin.

Il devrait ensuite fournir 1 fonction
<pre>
function plugin_example_cron_info($name)
</pre>
Qui retourne un tableau à 2 entrées pour la tâche $name comprenant 'description' (description localisée de la tâche) et 'parameter' (optionnel, description localisée du paramètre)

Et pour chaque tâche, une fonction d'exécution
<pre>
function plugin_example_cron_sample_run($task)
</pre>
L'objet $task permet d'enregistrer des évenements ($task->log) et des statistiques ($task->add/setVolume)
Le code retour doit être : 0 (rien à faire), >0 (terminé) ou <0 (à continuer)