Fr Plugin072to078 » History » Version 55

tsmr, 01/21/2011 02:22 PM

1 37 tsmr
h1. Migration d'un plugin de GLPI 0.72 vers 0.78
2 1 remi
3 4 remi
{{toc}}
4 4 remi
5 39 tsmr
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.
6 39 tsmr
Pour mettre à jour un plugin en 0.78, plusieurs étapes sont nécessaires :
7 39 tsmr
8 39 tsmr
 * Modification des tables et champs utilisés
9 39 tsmr
 * Modification des noms de fichiers
10 39 tsmr
 * Insertion des fonctions dans les classes
11 39 tsmr
 * Prise en charge des modifications de fonctions du cœur
12 39 tsmr
 * Nouveaux hooks disponibles
13 39 tsmr
 * Modification de la gestion des objets de type dropdown (listes déroulantes)
14 1 remi
15 42 yllen
16 5 remi
h2. Database
17 5 remi
18 2 tsmr
h3. CleanDB
19 1 remi
20 2 tsmr
Le coeur a subi d'importantes modification au niveau base de données :
21 2 tsmr
22 2 tsmr
https://forge.indepnet.net/wiki/glpi/CleanDbStudy
23 2 tsmr
24 41 yllen
25 40 yllen
26 43 yllen
27 43 yllen
28 43 yllen
h1. MODIFICATIONS A EFFECTUER DANS LES PLUGINS
29 43 yllen
30 43 yllen
31 43 yllen
h2. Règle de nommage des tables d'un plugin
32 43 yllen
33 43 yllen
*Nom de table d'un objet*
34 43 yllen
glpi_plugin_nomduplugin_objets (le nom de l'objet doit être au pluriel)
35 43 yllen
> ex: glpi_plugin_monplugin_profiles
36 43 yllen
37 43 yllen
*Nom de table d'un sous-objet*
38 43 yllen
glpi_plugin_nomduplugin_objetsousobjets (le nom de l'objet doit être au singulier et celui du sous-objet au pluriel)
39 43 yllen
> ex: glpi_plugin_monplugin_profiletypes
40 43 yllen
41 43 yllen
*Nom de table de 2 objets liés*
42 43 yllen
glpi_plugin_nomduplugin_objets1_objets2 (les noms des 2 objets liés doivent être au pluriel)
43 43 yllen
> ex: glpi_plugin_monplugin_profiles_entities
44 43 yllen
45 43 yllen
46 45 yllen
h2. Règle de nommage des pages d'un plugin
47 43 yllen
48 45 yllen
A chaque table du plugin doit correspondre un fichier  object.class (objet au singulier)
49 45 yllen
> ex: table glpi_plugin_monplugin_profiles  => fichier profile.class
50 43 yllen
51 45 yllen
52 52 yllen
h2. Modification dans les fichiers .class
53 52 yllen
54 52 yllen
Règle de nommage des class d'un plugin : new PluginNomdemonpluginProfile(); (nom de la class au singulier)
55 52 yllen
56 52 yllen
La fonction __construct () listant uniquement le nom de la table et le type n'est plus nécessaire
57 52 yllen
58 52 yllen
59 52 yllen
60 52 yllen
61 45 yllen
h2. Hook.php
62 45 yllen
63 45 yllen
h3. function plugin_monplugin_get_headings
64 45 yllen
65 45 yllen
h3. function plugin_monplugin_headings
66 45 yllen
67 45 yllen
Changement des paramètres d'appel de ces 2 fonctions ($type,$ID,$withtemplate => $item,$withtemplate)
68 45 yllen
<pre>
69 45 yllen
function plugin_monplugin_get_headings($item,$withtemplate) {
70 45 yllen
71 45 yllen
   $type = get_class($item);
72 45 yllen
   if ($type == 'Profile') {
73 45 yllen
</pre>
74 45 yllen
75 45 yllen
76 45 yllen
h3. function plugin_monplugin_headings_actions
77 45 yllen
78 45 yllen
Changement des paramètres d'appel de la fonction ($type => $item)
79 45 yllen
80 45 yllen
81 45 yllen
82 45 yllen
h2. setup.php
83 45 yllen
84 45 yllen
h3. function plugin_monplugin_init
85 45 yllen
86 45 yllen
Ajout des noms de class du plugin dans les types généraux du coeur
87 45 yllen
<pre>    
88 45 yllen
registerPluginType('typedemonplugin', 'PLUGIN_MONPLUGIN_TYPE', 'PluginMonpluginObjet',
89 45 yllen
                      array('classname'              => 'PluginMonpluginObjet',
90 45 yllen
                            'tablename'              => 'glpi_plugin_appliances_appliances',
91 45 yllen
                            'searchpage'             => 'index.php',
92 45 yllen
                            ...
93 45 yllen
</pre>
94 1 remi
devient
95 45 yllen
<pre>
96 54 yllen
Plugin::registerClass('PluginMonpluginProfile, array('classname' => 'PluginMonpluginObjet',                                         ...
97 45 yllen
</pre>
98 1 remi
99 1 remi
Modification des hooks sur les actions de GLPI
100 52 yllen
101 45 yllen
<pre>
102 1 remi
$PLUGIN_HOOKS['pre_item_add']['monplugin'] = 'plugin_pre_item_adde_monplugin';
103 1 remi
devient
104 1 remi
$PLUGIN_HOOKS['pre_item_add']['monplugin'] = array('Computer' =>'plugin_pre_item_update_monplugin');
105 52 yllen
</pre>
106 45 yllen
107 45 yllen
 
108 54 yllen
<pre> $PLUGIN_HOOKS['pre_item_delete']['monplugin'] = 'plugin_pre_item_monplugin_delete';
109 54 yllen
110 50 yllen
devient
111 54 yllen
$PLUGIN_HOOKS['pre_item_purge']['monplugin'] = objet => function
112 52 yllen
ou
113 50 yllen
$PLUGIN_HOOKS['pre_item_purge']['monplugin'] = objet => array('Class', 'Méthode')); </pre>
114 45 yllen
115 1 remi
116 51 yllen
h2. Chargement de l'environnement du plugin
117 45 yllen
118 54 yllen
<pre> useplugin('monplugin',true);
119 52 yllen
devient
120 54 yllen
Plugin::load('monplugin', true);</pre>
121 51 yllen
122 51 yllen
123 51 yllen
h2. Méthodes obligatoires
124 52 yllen
125 51 yllen
candelete....
126 45 yllen
127 45 yllen
128 45 yllen
129 45 yllen
130 40 yllen
h1. MODIFICATIONS DU COEUR IMPACTANT LES PLUGINS
131 42 yllen
132 41 yllen
h2. CommonDBTM
133 42 yllen
134 41 yllen
h3. showFormHeader
135 1 remi
136 45 yllen
Nouveau prototype
137 41 yllen
<pre>
138 1 remi
function showFormHeader ($options=array())
139 41 yllen
</pre>
140 1 remi
141 1 remi
Nouveau fonctionnement :
142 1 remi
* passage par défaut des form sur 2 colonnes
143 1 remi
* ouverture des <form, <div (tabsbody) et <table (tab_cadre_fixe)
144 1 remi
* champs cachés : entities_id, _no_message_link, template_name et is_template 
145 41 yllen
146 1 remi
Conseil : à utiliser conjointement avec showFormButtons
147 41 yllen
148 42 yllen
h3. showFormButtons
149 41 yllen
150 1 remi
Nouvelle fonction (factorisation du code)
151 1 remi
152 1 remi
<pre>
153 1 remi
function showFormButtons ($options=array())
154 1 remi
</pre>
155 1 remi
156 1 remi
Fonctionnement :
157 1 remi
* fermeture des <form, <div et <table
158 1 remi
* champs cachés : id
159 3 remi
160 42 yllen
h3. can / check
161 1 remi
162 1 remi
Nouveau prototype
163 1 remi
164 1 remi
<pre>
165 42 yllen
function can($ID,$right,&$input=NULL)
166 42 yllen
function check($ID,$right,&$input=NULL)
167 42 yllen
</pre>
168 42 yllen
169 42 yllen
Le paramètre $input, uniquement requis lors d'un ajout, attend les valeurs à ajouter (souvent le $_POST) et pas uniquement l'entité cible.
170 42 yllen
171 42 yllen
h3. cleanDBonPurge
172 42 yllen
173 42 yllen
Les méthodes fournies par le coeur (cleanRelationData/cleanRelationTable) nettoient les enregistrements liés des tables lors de la suppression d'un objet.
174 1 remi
* glpi_contracts_items (if registered in 'contract_types')
175 42 yllen
* glpi_documents_items (doc_types)
176 42 yllen
* glpi_infocoms (infocom_types)
177 42 yllen
* glpi_networkports et glpi_networkports_networkports (netport_types)
178 1 remi
* glpi_reservationitems (reservation_types)
179 42 yllen
* glpi_tickets (helpdesk_types)
180 1 remi
181 1 remi
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*.
182 1 remi
183 1 remi
184 1 remi
h3. Changement du nom des types d'objet
185 1 remi
186 1 remi
A vérifier dans le define.php (PROFILE_TYPE => 'Profile', COMPUTER_TYPE => 'Computer',.....)
187 1 remi
188 1 remi
189 54 yllen
h3. Variables globales
190 1 remi
191 54 yllen
Suppression de $INFOFORM_PAGES;
192 1 remi
193 54 yllen
Création de la constante globale  DROPDOWN_EMPTY_VALUE pour remplacer les ----- dans les dropdowns
194 1 remi
195 1 remi
196 54 yllen
h. Configuration
197 1 remi
198 54 yllen
<pre>$CFG_GLPI["mailing"]   =>   $CFG_GLPI["use_mailing"]</pre>
199 54 yllen
200 54 yllen
<pre> $CFG_GLPI["deleted_tables"]   =>   $item->maybeDeleted()</pre>
201 54 yllen
202 54 yllen
<pre> $CFG_GLPI["template_tables"]   =>  $item->maybeTemplate()</pre>
203 54 yllen
204 54 yllen
<pre> $CFG_GLPI["specif_entities_tables"]   =>   $item->isEntityAssign()</pre>
205 54 yllen
206 54 yllen
<pre> $CFG_GLPI["dropdowntree_tables"]   =>   $item instanceof CommonTreeDropdown </pre>
207 54 yllen
208 55 tsmr
$_SESSION['glpiID'] -> getLoginUserID()
209 54 yllen
210 54 yllen
h3. Fonctions supprimées
211 54 yllen
212 54 yllen
Liste alphabétique :
213 54 yllen
214 54 yllen
|| *Ancienne fonction* || *Alternative* ||
215 54 yllen
|| addDeviceDocument          || Document_Item->add ||
216 54 yllen
|| addDeviceContract          || Contract_Item->add ||
217 54 yllen
|| addDropdown                || Dropdown::import   ||
218 54 yllen
|| cleanCache();              || ||
219 54 yllen
|| dropdownAllItems           || Dropdown::showAllItems  ||
220 54 yllen
|| dropdownArrayValues[ReadOnly]  || Dropdown::showFromArray  ||
221 54 yllen
|| dropdownConnectPort        || NetworkPort::dropdownConnect  ||
222 54 yllen
|| dropdownHours              || Dropdown::showHours ||
223 54 yllen
|| dropdownInteger            || Dropdown::showInteger  ||
224 54 yllen
|| dropdownLanguages          || Dropdown::showLanguages  ||
225 54 yllen
|| dropdownNoValue            || ||
226 54 yllen
|| dropdownRules              || Rule::dropdown  ||
227 54 yllen
|| dropdownyesno              || Dropdown::showYesNo  ||
228 54 yllen
|| externalImportDropdown     || Dropdowwn::importExternal  ||
229 54 yllen
|| getYesNo                   || Dropdown::getYesNo  ||
230 54 yllen
|| globalManagementDropdown   || Dropdown::showGlobalSwitch  ||
231 54 yllen
|| haveTypeRight($type,'r')   || $item = new $type();  $item->canGlobal('r') ||
232 54 yllen
|| haveTypeRight($itemtype,'r')   || $item = new $itemtype();  $item->canView('r') ||
233 54 yllen
|| privatepublicSwitch        || Dropdown::showPrivatePublicSwitch  ||
234 54 yllen
235 54 yllen
|| getAllDropdown             || Dropdown::getStandardDropdownItemTypes  ||
236 54 yllen
237 54 yllen
238 54 yllen
|| dropdownRequestType(...);   || dropdownValue('glpi_requesttypes', ...) ||
239 54 yllen
240 54 yllen
|| getDocumentLink()           || Document->getDownloadLink() ||
241 54 yllen
|| getRequestTypeName(...)     || getDropdownName('glpi_requesttypes',...) ||
242 54 yllen
|| getContractSuppliers()      || Contract->getSuppliersNames()         || 
243 54 yllen
|| registerPluginType()      || Plugin::registerClass()         || 
244 54 yllen
|| showContractAssociated()    || Contract::showAssociated() ||
245 54 yllen
|| showDocumentAssociated()    || Document::showAssociated() ||
246 54 yllen
|| showInfocomForm()           || Infocom::showForItem() ||
247 54 yllen
|| showSaveBookmarkButton(...) || Bookmark::showSaveButton(...) ||
248 54 yllen
|| dropdownNoneReadWrite(...) || Profile::dropdownNoneReadWrite(...) ||
249 54 yllen
|| getPlanningState(...) || TicketPlanning::getState(...) ||
250 54 yllen
|| dropdownPlanningState(...) || TicketPlanning::dropdownState(...) ||
251 54 yllen
|| dropdown(...) || CommoDropdown::dropdown(...) ||
252 54 yllen
|| dropdownValue(...) || CommonDropdown::dropdownValue(...) ||
253 54 yllen
|| dropdownNoValue(...) || CommonDropdown::dropdownNoValue(...) ||
254 54 yllen
|| getDropdownName(...) || CommonDropdown::getDropdownName(...) ||
255 54 yllen
256 54 yllen
257 28 remi
h1. A REVOIR
258 28 remi
259 28 remi
h4. getSearchOptions
260 28 remi
261 28 remi
Cette nouvelle méthode doit retourner les options de recherche pour le type courant.
262 28 remi
263 29 remi
h2. Variables de session
264 32 remi
265 28 remi
<pre>
266 28 remi
$_SESSION["glpiview_ID"] remplacé par $_SESSION["glpiis_ids_visible"] 
267 31 remi
</pre>
268 28 remi
269 33 walid
h2. Utilisation Mbstring pour gérer UTF8
270 36 walid
271 36 walid
<pre>
272 36 walid
substr remplacé par utf8_substr
273 36 walid
</pre>
274 36 walid
<pre>
275 36 walid
utf8_decode remplacé par decodeFromUtf8
276 48 tsmr
</pre>
277 27 remi
<pre>
278 27 remi
utf8_encode remplacé par encodeFromUtf8
279 27 remi
</pre>
280 27 remi
<pre>
281 27 remi
strtolower remplacé par utf8_strtolower
282 18 remi
</pre>
283 21 remi
<pre>
284 21 remi
strtoupper remplacé par utf8_strtoupper
285 21 remi
</pre>
286 21 remi
287 21 remi
288 21 remi
289 21 remi
h2. Classes renommées
290 21 remi
291 38 ddurieux
<pre>
292 38 ddurieux
Enterprise => Supplier
293 38 ddurieux
</pre>
294 38 ddurieux
295 38 ddurieux
h2. HOOK supprimés
296 38 ddurieux
297 38 ddurieux
* plugin_example_getAddSearchOption() : remplacé par la méthode getSearchOptions du type et le hook plugin_example_getAddSearchOptions
298 38 ddurieux
299 38 ddurieux
h2. HOOK ajoutés
300 38 ddurieux
301 38 ddurieux
* plugin_example_getAddSearchOptions($itemtype) retourne les options de recherche ajoutées par le plugin aux types existants
302 47 tsmr
* 0.78.2 : plugin_example_searchOptionsValues($params = array()) permet de faire des recherche sur le moteur avec un drodpdown particulier (interne au plugin)
303 47 tsmr
* 0.78.2 : plugin_example_displayConfigItem($type,$ID,$data,$num) Permet de personnaliser le style du <td> dans la liste des objets
304 38 ddurieux
305 12 remi
306 12 remi
h2. Tâche planifiée
307 12 remi
308 12 remi
Le hook *'cron'* n'est plus utilisé
309 12 remi
310 12 remi
Lors de l'installation un plugin peut enregistrer une tâche en utilisant
311 12 remi
<pre>
312 12 remi
   CronTask::Register('pluginame', 'taskname', DAY_TIMESTAMP, array('param'=>50));
313 12 remi
</pre>
314 12 remi
La suppression est automatiquement réalisée par le coeur lors de la désinstallation du plugin.
315 12 remi
316 12 remi
Il devrait ensuite fournir 1 fonction
317 12 remi
<pre>
318 12 remi
function plugin_example_cron_info($name)
319 12 remi
</pre>
320 12 remi
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)
321 12 remi
322 12 remi
Et pour chaque tâche, une fonction d'exécution
323 12 remi
<pre>
324 12 remi
function plugin_example_cron_sample_run($task)
325 12 remi
</pre>
326 12 remi
L'objet $task permet d'enregistrer des évenements ($task->log) et des statistiques ($task->add/setVolume)
327 12 remi
Le code retour doit être : 0 (rien à faire), >0 (terminé) ou <0 (à continuer)