Il existe un plugin example, présentant l'ensemble des fonctionnalités https://forge.indepnet.net/repositories/show/example

Le plugin room est un cas concret simple assez complet également https://forge.indepnet.net/repositories/show/room

Publication Linux-Mag : http://www.maje.biz/downloads/glpi-plugin.pdf

Comment écrire un plugin pour GLPI ?

Le plug-in se présente sous la forme d'un dossier à ajouter dans le répertoire plugins de l'arborescence de GLPI.
Ce dossier va contenir tous les fichiers php (et images par exemple). En résumé, tout ce qui se rapporte au plug-in.

Ce nom de répertoire ne doit comprendre que des caractères alphanumériques (pas de - _ . ou autre)

Un plugin ne modifie jamais la structure des tables de GLPI. Il se contente d'ajouter des tables dans la base de donnée MySQL, pour gérer ses propres données ou alors d'écrire certaines données dans les tables existantes (via l'API du coeur).

Conventions de programmation

1. Noms de tables

  • Vos noms de tables doivent respecter la règle suivante : glpi_plugin_<plugin_name>_XXXX
  • Si vous utilisez des tables de type dropdown (liste de valeurs), elles doivent respecter la règle suivante : glpi_dropdown_plugin_<plugin_name>_XXXX

2. Bien respecter l'arborescence des fichiers du plugin :

  • Un répertoire "locales" : dictionnaires
  • Les dictionnaires seront du type : fr_FR.php / en_GB.php
  • Un répertoire "docs" :
  • Readme.txt, Lisezmoi.txt, Roadmap.txt, Changelog.txt
  • Un répertoire "inc" : contient les classes et fonctions
  • Les noms de fichiers devront être taggués pour les fonctions, par exemple : plugin_<plugin_name>.db.function.php
  • Les noms de fichiers devront être taggués pour les classes, par exemple : plugin_<plugin_name>.db.class.php
  • Un répertoire "front" : contient les formulaires
  • Les noms de fichiers devront être taggués, par exemple :
  • pour le formulaire de création/édition d'un objet : plugin_<plugin_name>.<object>.form.php
  • pour l'affichage du moteur de recherche associé à un objet : plugin_<plugin_name>.php
  • Un répertoire "pics" : contient les images
  • Un répertoire "ajax" : contient les fichiers pour tout ce qui touche à l'ajax (notament l'affichage onglets)
  • A la racine :
  • en obligatoire :
  • hook.php
  • setup.php
  • en facultatif
  • index.php
  • Si votre plugin doit créer des fichiers temporaires :
  • ceux-ci doivent être créés dans le répertoire files de GLPI sous files/_plugins/<plugin_name>.
  • il faut bien penser à créer le répertoire files/_plugins/<plugin_name> lors de l'installation du plugin et à le supprimer lors de sa suppression

Ceci permet d'éviter la gestion des droits d'écriture à chaque release de votre plugin.
Les droits lors de l'installation ou la mise à jour de GLPI s'appliqueront.
Tout ceci dans le but de ne pas interférer avec le core de GLPI.

3. Gestion des noms de fonctions

  • Les classes créées devront être tagguées : class Plugin<Plugin_name>Xxxx (exemple : PluginExampleDisplay)
  • Les fonctions hors de ces classes devront être tagguées : function plugin_<plugin_name>_<fonction> (exemple : plugin_example_getType())

4. Look et Aspect du plugin :

Pour qu'il s'intègre au mieux dans GLPI, le mieux est de réutiliser les classes de mise en forme déjà définies et utilisées dans GLPI.
Vous trouverez l'ensemble de ces définitions dans le fichier CSS de GLPI.

Merci de respecter ceci afin d'harmoniser les plugins et leurs futurs développements.

Avant de commencer

  • Il est toujours utile de :
  • passer en mode http://glpi-project.org/wiki/doku.php?id=fr:config:debug | débug
  • activer le tracage des logs (dans la configuration de GLPI), c'est d'une aide précieuse dans les développements et la vérification du bon fonctionnement
  • vérifier que MySQL est bien en mode strict (dans la section [mysqld] du fichier my.cnf ajouter :
sql-mode        = STRICT_ALL_TABLES

et relancer MySQL)

Structure des fichiers de base du plugins ainsi que la définition des hooks GLPI

  • Si un plugin n'est pas installé, aucun de ses fichiers n'est chargé.
  • Lors de l'installation les fichiers setup.php et hook.php sont chargés

La procédure l'installation et la désinstallation d'un plugin sont gérées de manière standard par le coeur de GLPI. Celui-ci appelle des fonctions définies dans le fichier hook.php

Voir les explications du détail des fichiers :

Localisation

Tous les textes du plugin qui seront affichés dans GLPI doivent être externalisés dans un fichier, afin de pouvoir facilement traduire l'interface (juste besoin de traduire un fichier).
Les fichiers de langue se trouvent dans le répertoire "locales"
La convention pour le nommage d'un fichier de langue est le même que celui de GLPI et utilise la norme i18n. Par exemple :
  • fr_FR pour le français (de France),
  • nl_NL pour le néerlandais
  • nl_BE pour le flamand
  • en_GB pour l'anglais (d'Angleterre)

A l'intérieur du fichier, les libellés sont tous stockés dans un tableau dont voici un exemple :

$LANG['<plugin_name>']['title'][0] = "mon titre";
$LANG['<plugin_name>']['myplugin'][1] = "libellé 1";
$LANG['<plugin_name>']['myplugin'][2] = "libellé 2";

Les fichiers doivent utiliser l'encodage UTF8

Le fichier de langue correspondant à la langue courante de l'utilisateur et sera chargé dynamiquement.
S'il n'existe pas GLPI tentera de charger successivement celui de la langue par défaut, de l'anglais puis du français.

Interactions diverses

Ajout Javascript et CSS

Vous pouvez ajouter des scripts javascript pour vos propres besoins ainsi que des fichiers de style CSS en utilisant les définitions suivantes :

$PLUGIN_HOOKS['add_javascript']['<plugin_name>']="FILENAME.js";
$PLUGIN_HOOKS['add_css']['<plugin_name>']="FILENAME.css";

Utilisation de l'API de GLPI

Squelette d'une page affichée dans GLPI

Une page php incluse dans GLPI ou dans l’un de ses plugins doit au minimum définir :
  • la constante GLPI_ROOT contenant le chemin vers la racine de GLPI
define('GLPI_ROOT', '../..');
  • les includes
include (GLPI_ROOT."/inc/includes.php");

Si on veut utiliser les fonctions des objets de GLPI, il faut définir avant l'inclusion de /inc/define.php, un tableau $NEEDED_ITEMS contenant la liste des fonctions d'objets GLPI à charger. (Le nom est le nom du fichier dans le répertoire inc de GLPI sans le .class.php à la fin.)
Exemple :

$NEEDED_ITEMS=array("search");

Elle contient ensuite les appels de fonctions suivantes :

La fonction commonHeader affiche l’entête d’une page GLPI, menu compris. Elle prend en paramètre minimum le titre de la page.

La fonction commonFooter affiche le pied de page par défaut d’une page GLPI.

Les autres affichages de la page se font entre la fonction commonHeader et commonFooter.

Par exemple : https://forge.indepnet.net/repositories/entry/example/trunk/index.php

Cas particulier pour les posts et formulaire

  • La fonction glpi_header redirige la page vers une autre page. Elle prend en paramètres l’URL de la page cible.
  • Mettre les includes dans le fichier hook.php, ce qui permettra à la fonction usePlugin(<plugin_name>, true) de charger tous les fichiers inc du plugin ainsi que le hook.Le but étant de limiter le chargement excessif d'include dans le setup.php.

Utiliser CommonDBTM

Si vous définissez un nouveau type il vous faut également définir la classe associée à ce nouveau type.
Elle doit hériter de la classe CommonDBTM qui permet de s'abstraire de tous les accès directs à la base de données.
Sa définition minimale est du type :

class PluginExample extends CommonDBTM {
    function plugin_example () {
        $this->table="glpi_plugin_example";
        $this->type=PLUGIN_EXAMPLE_TYPE;
    }
};

Pour plus d'infos, sur les fonctions que vous pouvez surcharger, la documentation de cette classe se trouve ici :
https://forge.indepnet.net/embedded/glpi/classCommonDBTM.html