Fr Plugin072to078 » History » Version 51

yllen, 01/21/2011 11:24 AM

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 45 yllen
h2. Hook.php
53 45 yllen
54 45 yllen
h3. function plugin_monplugin_get_headings
55 45 yllen
56 45 yllen
h3. function plugin_monplugin_headings
57 45 yllen
58 45 yllen
59 45 yllen
Changement des paramètres d'appel de ces 2 fonctions ($type,$ID,$withtemplate => $item,$withtemplate)
60 45 yllen
<pre>
61 45 yllen
function plugin_monplugin_get_headings($item,$withtemplate) {
62 45 yllen
63 45 yllen
   $type = get_class($item);
64 45 yllen
   if ($type == 'Profile') {
65 45 yllen
</pre>
66 45 yllen
67 45 yllen
68 45 yllen
h3. function plugin_monplugin_headings_actions
69 45 yllen
70 45 yllen
Changement des paramètres d'appel de la fonction ($type => $item)
71 45 yllen
72 45 yllen
73 45 yllen
74 45 yllen
h2. setup.php
75 45 yllen
76 45 yllen
h3. function plugin_monplugin_init
77 45 yllen
78 45 yllen
Ajout des noms de class du plugin dans les types généraux du coeur
79 45 yllen
80 45 yllen
<pre>    
81 45 yllen
registerPluginType('typedemonplugin', 'PLUGIN_MONPLUGIN_TYPE', 'PluginMonpluginObjet',
82 45 yllen
                      array('classname'              => 'PluginMonpluginObjet',
83 45 yllen
                            'tablename'              => 'glpi_plugin_appliances_appliances',
84 45 yllen
                            'searchpage'             => 'index.php',
85 45 yllen
                            ...
86 45 yllen
</pre>
87 45 yllen
devient
88 45 yllen
89 45 yllen
<pre>
90 45 yllen
Plugin::registerClass('PluginMonpluginProfile, array('classname' => 'PluginMonpluginObjet',
91 45 yllen
                                               ...
92 45 yllen
93 45 yllen
</pre>
94 45 yllen
95 45 yllen
Modification des hooks sur les actions de GLPI
96 45 yllen
On passe de 
97 45 yllen
<pre>
98 49 tsmr
$PLUGIN_HOOKS['pre_item_add']['monplugin'] = 'plugin_pre_item_adde_monplugin';
99 45 yllen
</pre>
100 45 yllen
101 45 yllen
à 
102 45 yllen
103 45 yllen
<pre>
104 45 yllen
$PLUGIN_HOOKS['pre_item_add']['monplugin'] = array('Computer' =>'plugin_pre_item_update_monplugin');
105 45 yllen
</pre>
106 45 yllen
107 45 yllen
Remplacement du 
108 45 yllen
<pre> $PLUGIN_HOOKS['pre_item_delete']['monplugin'] = 'plugin_pre_item_monplugin_delete'; </pre>
109 45 yllen
par 
110 50 yllen
<pre> $PLUGIN_HOOKS['pre_item_purge']['monplugin'] = objet => function
111 50 yllen
ou
112 50 yllen
$PLUGIN_HOOKS['pre_item_purge']['monplugin'] = objet => array('Class', 'Méthode')); </pre>
113 45 yllen
114 45 yllen
115 51 yllen
h2. Chargement de l'environnement du plugin
116 45 yllen
117 51 yllen
Remplacement de
118 51 yllen
<pre> useplugin('monplugin',true);</pre>
119 51 yllen
par
120 51 yllen
<pre> Plugin::load('monplugin', true);</pre>
121 51 yllen
122 51 yllen
123 51 yllen
h2. Méthodes obligatoires
124 51 yllen
candelete....
125 45 yllen
126 45 yllen
127 45 yllen
128 45 yllen
129 40 yllen
h1. MODIFICATIONS DU COEUR IMPACTANT LES PLUGINS
130 42 yllen
131 41 yllen
h2. CommonDBTM
132 42 yllen
133 41 yllen
h3. showFormHeader
134 1 remi
135 45 yllen
Nouveau prototype
136 41 yllen
<pre>
137 1 remi
function showFormHeader ($options=array())
138 41 yllen
</pre>
139 1 remi
140 1 remi
Nouveau fonctionnement :
141 1 remi
* passage par défaut des form sur 2 colonnes
142 1 remi
* ouverture des <form, <div (tabsbody) et <table (tab_cadre_fixe)
143 1 remi
* champs cachés : entities_id, _no_message_link, template_name et is_template 
144 41 yllen
145 1 remi
Conseil : à utiliser conjointement avec showFormButtons
146 41 yllen
147 42 yllen
h3. showFormButtons
148 41 yllen
149 1 remi
Nouvelle fonction (factorisation du code)
150 1 remi
151 1 remi
<pre>
152 1 remi
function showFormButtons ($options=array())
153 1 remi
</pre>
154 1 remi
155 1 remi
Fonctionnement :
156 1 remi
* fermeture des <form, <div et <table
157 1 remi
* champs cachés : id
158 3 remi
159 42 yllen
h3. can / check
160 1 remi
161 1 remi
Nouveau prototype
162 1 remi
163 1 remi
<pre>
164 42 yllen
function can($ID,$right,&$input=NULL)
165 42 yllen
function check($ID,$right,&$input=NULL)
166 42 yllen
</pre>
167 42 yllen
168 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.
169 42 yllen
170 42 yllen
h3. cleanDBonPurge
171 42 yllen
172 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.
173 42 yllen
* glpi_contracts_items (if registered in 'contract_types')
174 42 yllen
* glpi_documents_items (doc_types)
175 42 yllen
* glpi_infocoms (infocom_types)
176 42 yllen
* glpi_networkports et glpi_networkports_networkports (netport_types)
177 42 yllen
* glpi_reservationitems (reservation_types)
178 42 yllen
* glpi_tickets (helpdesk_types)
179 42 yllen
180 46 tsmr
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*.
181 42 yllen
182 42 yllen
183 44 yllen
h2. Changement du nom des types d'objet
184 44 yllen
185 44 yllen
A vérifier dans le define.php (PROFILE_TYPE => 'Profile', COMPUTER_TYPE => 'Computer',.....)
186 42 yllen
187 42 yllen
188 42 yllen
189 42 yllen
190 42 yllen
191 42 yllen
192 42 yllen
h1. A REVOIR
193 41 yllen
194 41 yllen
h4. getSearchOptions
195 11 remi
196 21 remi
Cette nouvelle méthode doit retourner les options de recherche pour le type courant.
197 17 tsmr
198 17 tsmr
h2. Variables de session
199 17 tsmr
200 17 tsmr
<pre>
201 17 tsmr
$_SESSION["glpiview_ID"] remplacé par $_SESSION["glpiis_ids_visible"] 
202 17 tsmr
</pre>
203 17 tsmr
204 17 tsmr
h2. Utilisation Mbstring pour gérer UTF8
205 17 tsmr
206 17 tsmr
<pre>
207 17 tsmr
substr remplacé par utf8_substr
208 17 tsmr
</pre>
209 9 tsmr
<pre>
210 9 tsmr
utf8_decode remplacé par decodeFromUtf8
211 9 tsmr
</pre>
212 9 tsmr
<pre>
213 9 tsmr
utf8_encode remplacé par encodeFromUtf8
214 6 tsmr
</pre>
215 10 tsmr
<pre>
216 18 remi
strtolower remplacé par utf8_strtolower
217 1 remi
</pre>
218 28 remi
<pre>
219 28 remi
strtoupper remplacé par utf8_strtoupper
220 28 remi
</pre>
221 28 remi
222 28 remi
h2. Configuration
223 28 remi
224 28 remi
<pre>
225 28 remi
$CFG_GLPI["mailing"] remplacé par $CFG_GLPI["use_mailing"]
226 28 remi
</pre>
227 29 remi
228 32 remi
h2. Fonctions supprimées
229 28 remi
230 28 remi
Liste alphabétique :
231 31 remi
232 28 remi
|| *Ancienne fonction* || *Alternative* ||
233 33 walid
|| addDeviceDocument()        || DocumentItem->add() ||
234 36 walid
|| addDeviceContract()        || ContractItem->add() ||
235 36 walid
|| cleanCache(); || ||
236 36 walid
|| dropdownRequestType(...);   || dropdownValue('glpi_requesttypes', ...) ||
237 36 walid
|| getDocumentLink()           || Document->getDownloadLink() ||
238 36 walid
|| getRequestTypeName(...)     || getDropdownName('glpi_requesttypes',...) ||
239 36 walid
|| getContractSuppliers()      || Contract->getSuppliersNames()         || 
240 48 tsmr
|| registerPluginType()      || Plugin::registerClass()         || 
241 27 remi
|| showContractAssociated()    || Contract::showAssociated() ||
242 27 remi
|| showDocumentAssociated()    || Document::showAssociated() ||
243 27 remi
|| showInfocomForm()           || Infocom::showForItem() ||
244 27 remi
|| showSaveBookmarkButton(...) || Bookmark::showSaveButton(...) ||
245 27 remi
|| dropdownNoneReadWrite(...) || Profile::dropdownNoneReadWrite(...) ||
246 18 remi
|| getPlanningState(...) || TicketPlanning::getState(...) ||
247 21 remi
|| dropdownPlanningState(...) || TicketPlanning::dropdownState(...) ||
248 21 remi
|| dropdown(...) || CommoDropdown::dropdown(...) ||
249 21 remi
|| dropdownValue(...) || CommonDropdown::dropdownValue(...) ||
250 21 remi
|| dropdownNoValue(...) || CommonDropdown::dropdownNoValue(...) ||
251 21 remi
|| getDropdownName(...) || CommonDropdown::getDropdownName(...) ||
252 21 remi
253 21 remi
h2. Classes renommées
254 21 remi
255 38 ddurieux
<pre>
256 38 ddurieux
Enterprise => Supplier
257 38 ddurieux
</pre>
258 38 ddurieux
259 38 ddurieux
h2. HOOK supprimés
260 38 ddurieux
261 38 ddurieux
* plugin_example_getAddSearchOption() : remplacé par la méthode getSearchOptions du type et le hook plugin_example_getAddSearchOptions
262 38 ddurieux
263 38 ddurieux
h2. HOOK ajoutés
264 38 ddurieux
265 38 ddurieux
* plugin_example_getAddSearchOptions($itemtype) retourne les options de recherche ajoutées par le plugin aux types existants
266 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)
267 47 tsmr
* 0.78.2 : plugin_example_displayConfigItem($type,$ID,$data,$num) Permet de personnaliser le style du <td> dans la liste des objets
268 38 ddurieux
269 12 remi
270 12 remi
h2. Tâche planifiée
271 12 remi
272 12 remi
Le hook *'cron'* n'est plus utilisé
273 12 remi
274 12 remi
Lors de l'installation un plugin peut enregistrer une tâche en utilisant
275 12 remi
<pre>
276 12 remi
   CronTask::Register('pluginame', 'taskname', DAY_TIMESTAMP, array('param'=>50));
277 12 remi
</pre>
278 12 remi
La suppression est automatiquement réalisée par le coeur lors de la désinstallation du plugin.
279 12 remi
280 12 remi
Il devrait ensuite fournir 1 fonction
281 12 remi
<pre>
282 12 remi
function plugin_example_cron_info($name)
283 12 remi
</pre>
284 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)
285 12 remi
286 12 remi
Et pour chaque tâche, une fonction d'exécution
287 12 remi
<pre>
288 12 remi
function plugin_example_cron_sample_run($task)
289 12 remi
</pre>
290 12 remi
L'objet $task permet d'enregistrer des évenements ($task->log) et des statistiques ($task->add/setVolume)
291 12 remi
Le code retour doit être : 0 (rien à faire), >0 (terminé) ou <0 (à continuer)