Fr Plugin072to078 » History » Version 67

yllen, 05/31/2011 05:35 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 66 yllen
https://forge.indepnet.net/projects/glpi/wiki/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 64 yllen
$PLUGIN_HOOKS['pre_item_add']['monplugin'] = 'plugin_pre_item_update_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 45 yllen
117 51 yllen
h2. Méthodes obligatoires
118 52 yllen
119 62 yllen
- static function getTypeName()
120 62 yllen
- function canCreate()
121 62 yllen
- function canView()
122 62 yllen
- function canDelete()
123 62 yllen
- function cleanDBonPurge()
124 45 yllen
125 45 yllen
126 45 yllen
127 40 yllen
h1. MODIFICATIONS DU COEUR IMPACTANT LES PLUGINS
128 42 yllen
129 41 yllen
h2. CommonDBTM
130 42 yllen
131 61 yllen
h3. defineTabs
132 61 yllen
133 61 yllen
Nouveau prototype
134 61 yllen
<pre>function defineTabs ($options=array())</pre>
135 61 yllen
136 61 yllen
137 1 remi
h3. showFormHeader
138 41 yllen
139 1 remi
Nouveau prototype
140 61 yllen
<pre>function showFormHeader ($options=array())</pre>
141 1 remi
142 1 remi
Nouveau fonctionnement :
143 1 remi
* passage par défaut des form sur 2 colonnes
144 1 remi
* ouverture des <form, <div (tabsbody) et <table (tab_cadre_fixe)
145 1 remi
* champs cachés : entities_id, _no_message_link, template_name et is_template 
146 42 yllen
147 1 remi
Conseil : à utiliser conjointement avec showFormButtons
148 41 yllen
149 1 remi
h3. showFormButtons
150 1 remi
151 1 remi
Nouvelle fonction (factorisation du code)
152 1 remi
153 61 yllen
<pre>function showFormButtons ($options=array())</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 1 remi
* 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 1 remi
* glpi_reservationitems (reservation_types)
178 42 yllen
* glpi_tickets (helpdesk_types)
179 1 remi
180 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*.
181 1 remi
182 1 remi
183 1 remi
h3. Changement du nom des types d'objet
184 1 remi
185 1 remi
A vérifier dans le define.php (PROFILE_TYPE => 'Profile', COMPUTER_TYPE => 'Computer',.....)
186 1 remi
187 1 remi
188 59 yllen
h3. Classes renommées
189 59 yllen
190 59 yllen
<pre>Enterprise   =>   Supplier</pre>
191 59 yllen
192 59 yllen
193 1 remi
h3. Variables de session
194 58 yllen
195 59 yllen
<pre>$_SESSION["glpiview_ID"]  =>  $_SESSION["glpiis_ids_visible"] </pre>
196 59 yllen
197 60 yllen
<pre>$_SESSION['glpiID']       =>  getLoginUserID()</pre>
198 58 yllen
199 54 yllen
200 1 remi
h3. Variables globales
201 54 yllen
202 63 yllen
203 1 remi
Suppression de $INFOFORM_PAGES;
204 54 yllen
205 1 remi
Création de la constante globale  DROPDOWN_EMPTY_VALUE pour remplacer les ----- dans les dropdowns
206 1 remi
207 67 yllen
$LINK_ID_TABLE[$type] => $item->getTable
208 67 yllen
209 56 tsmr
210 1 remi
h3. Configuration
211 54 yllen
212 60 yllen
<pre>$CFG_GLPI["mailing"]                   =>   $CFG_GLPI["use_mailing"]</pre>
213 54 yllen
214 60 yllen
<pre> $CFG_GLPI["deleted_tables"]           =>   $item->maybeDeleted()</pre>
215 1 remi
216 63 yllen
<pre> $CFG_GLPI["template_tables"]          =>   $item->maybeTemplate()</pre>
217 54 yllen
218 54 yllen
<pre> $CFG_GLPI["specif_entities_tables"]   =>   $item->isEntityAssign()</pre>
219 1 remi
220 60 yllen
<pre> $CFG_GLPI["dropdowntree_tables"]      =>   $item instanceof CommonTreeDropdown </pre>
221 1 remi
222 63 yllen
<pre> $CFG_GLPI["devices_tables"]           =>                                 </pre>
223 63 yllen
224 63 yllen
<pre> $CFG_GLPI["recursive_type"]           =>   $item->maybeRecursive()</pre>
225 58 yllen
226 1 remi
227 1 remi
h3. Fonctions supprimées
228 1 remi
229 1 remi
Liste alphabétique :
230 1 remi
231 58 yllen
|| *Ancienne fonction* || *Alternative* ||
232 58 yllen
|| addDeviceDocument()              || Document_Item->add(...) ||
233 58 yllen
|| addDeviceContract()              || Contract_Item->add(...) ||
234 58 yllen
|| addDropdown()                    || Dropdown::import(...)   ||
235 58 yllen
|| cleanCache();                    || ||
236 58 yllen
|| dropdownAllItems()               || Dropdown::showAllItems(...)  ||
237 58 yllen
|| dropdownArrayValues[ReadOnly]()  || Dropdown::showFromArray(...)  ||
238 58 yllen
|| dropdownConnectPort()            || NetworkPort::dropdownConnect(...)  ||
239 58 yllen
|| dropdownHours()                  || Dropdown::showHours(...) ||
240 58 yllen
|| dropdownInteger()                || Dropdown::showInteger(...)  ||
241 58 yllen
|| dropdownLanguages()              || Dropdown::showLanguages(...)  ||
242 58 yllen
|| dropdownNoneReadWrite()          || Profile::dropdownNoneReadWrite(...) ||
243 58 yllen
|| dropdownNoValue()                || Dropdown::show(...) ||
244 58 yllen
|| dropdownPlanningState()          || Planning::dropdownState(...) ||
245 58 yllen
|| dropdownRequestType(...)         || Dropdown::show('RequestType', ...) ||
246 58 yllen
|| dropdownRules()                  || Rule::dropdown()  ||
247 58 yllen
|| dropdownValue()                  || Dropdown::show(...) ||
248 58 yllen
|| dropdownyesno()                  || Dropdown::showYesNo(...)  ||
249 58 yllen
|| externalImportDropdown()         || Dropdowwn::importExternal(...)  ||
250 58 yllen
|| getAllDropdown()                 || Dropdown::getStandardDropdownItemTypes()  ||
251 58 yllen
|| getContractSuppliers()           || Contract->getSuppliersNames()         || 
252 58 yllen
|| getDocumentLink()                || Document->getDownloadLink(...) ||
253 58 yllen
|| getDropdownName()                || Dropdown::getDropdownName(...) ||
254 58 yllen
|| getPlanningState()               || Planning::getState(...) ||
255 58 yllen
|| getRequestTypeName(...)          || Dropdown::getDropdownName('glpi_requesttypes',...) ||
256 58 yllen
|| getYesNo()                       || Dropdown::getYesNo(...)  ||
257 58 yllen
|| globalManagementDropdown()       || Dropdown::showGlobalSwitch(...)  ||
258 58 yllen
|| haveTypeRight($type,'r')         || $item = new $type();  $item->canGlobal('r') ||
259 58 yllen
|| haveTypeRight($itemtype,'r')     || $item = new $itemtype();  $item->canView('r') ||
260 58 yllen
|| privatepublicSwitch()            || Dropdown::showPrivatePublicSwitch(...)  ||
261 58 yllen
|| registerPluginType()             || Plugin::registerClass(...)         ||
262 58 yllen
|| showContractAssociated()         || Contract::showAssociated(...) ||
263 58 yllen
|| showDocumentAssociated()         || Document::showAssociated(...) ||
264 28 remi
|| showInfocomForm()                || Infocom::showForItem(...) ||
265 28 remi
|| showSaveBookmarkButton()         || Bookmark::showSaveButton(...) ||
266 1 remi
|| useplugin                        || Plugin::load(...)  ||
267 1 remi
268 1 remi
269 59 yllen
h3. getSearchOptions
270 1 remi
271 59 yllen
Cette nouvelle méthode doit retourner les options de recherche pour le type courant.
272 1 remi
273 1 remi
274 1 remi
h3. Utilisation Mbstring pour gérer UTF8
275 1 remi
276 1 remi
<pre>substr        =>   utf8_substr</pre>
277 60 yllen
278 1 remi
<pre>utf8_decode   =>   decodeFromUtf8</pre>
279 60 yllen
280 59 yllen
<pre>utf8_encode   =>   encodeFromUtf8</pre>
281 60 yllen
282 59 yllen
<pre>strtolower    =>   utf8_strtolower</pre>
283 59 yllen
284 38 ddurieux
<pre>strtoupper    =>   utf8_strtoupper</pre>
285 1 remi
286 38 ddurieux
287 62 yllen
h3. HOOK supprimés
288 38 ddurieux
289 38 ddurieux
* plugin_example_getAddSearchOption() : remplacé par la méthode getSearchOptions du type et le hook plugin_example_getAddSearchOptions
290 38 ddurieux
291 62 yllen
h3. HOOK ajoutés
292 38 ddurieux
293 47 tsmr
* plugin_example_getAddSearchOptions($itemtype) retourne les options de recherche ajoutées par le plugin aux types existants
294 64 yllen
* 0.78.2 : plugin_example_searchOptionsValues($params = array()) permet de faire des recherche sur le moteur avec un dropdown particulier (interne au plugin)
295 38 ddurieux
* 0.78.2 : plugin_example_displayConfigItem($type,$ID,$data,$num) Permet de personnaliser le style du <td> dans la liste des objets
296 65 remi
* 0.78.3 : 'post_init' : permet de réaliser des traitements après l'init des autres plugins
297 12 remi
298 12 remi
h2. Tâche planifiée
299 12 remi
300 12 remi
Le hook *'cron'* n'est plus utilisé
301 12 remi
302 12 remi
Lors de l'installation un plugin peut enregistrer une tâche en utilisant
303 12 remi
<pre>
304 12 remi
   CronTask::Register('pluginame', 'taskname', DAY_TIMESTAMP, array('param'=>50));
305 12 remi
</pre>
306 12 remi
La suppression est automatiquement réalisée par le coeur lors de la désinstallation du plugin.
307 12 remi
308 12 remi
Il devrait ensuite fournir 1 fonction
309 12 remi
<pre>
310 12 remi
function plugin_example_cron_info($name)
311 12 remi
</pre>
312 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)
313 12 remi
314 12 remi
Et pour chaque tâche, une fonction d'exécution
315 12 remi
<pre>
316 12 remi
function plugin_example_cron_sample_run($task)
317 12 remi
</pre>
318 12 remi
L'objet $task permet d'enregistrer des évenements ($task->log) et des statistiques ($task->add/setVolume)
319 1 remi
Le code retour doit être : 0 (rien à faire), >0 (terminé) ou <0 (à continuer)