Projet

Général

Profil

Plugin » Historique » Version 21

Marc Leygnac, 03/02/2019 11:16

1 13 Marc Leygnac
h1. Coder un plugin pour GEPI
2 1
3 10 Julien Jocal
4 13 Marc Leygnac
* Chaque plugin est stocké dans un sous-dossier du dossier *mod_plugins* de GEPI. Le nom du dossier du plugin, défini dans le fichier *plugin.xml*, ne comporte ni point ni accent, et les espaces sont remplacés par des tirets bas "_".
5 1
6 13 Marc Leygnac
* La mise en fonction d'un plugin consiste à copier son dossier dans le dossier *mod_plugins*, puis en mode administrateur (Gestion des modules/Gérer les plugins) à "installer" et à "ouvrir" le plugin (un plugin peut être "installé" sans nécessairement être ouvert).
7 1
8 15 Marc Leygnac
* Chaque plugin contient un fichier de paramétrage *plugin.xml* utilisé lors de son "installation" et de sa "désinstallation".
9 1
10 15 Marc Leygnac
* La gestion des droits est assurée par une méthode verifDroits() (propre au module Plugins) qui consulte la table *plugins_autorisations*, et éventuellement cette gestion est complétée par la fonction *calcul_autorisation_...()*.
11 10 Julien Jocal
12 13 Marc Leygnac
* Les tables de la base GEPI utilisées par le module Plugins sont *plugins* (liste des plugins présents), *plugins_menus* (page d'accueil et barre de menu) et *plugins_autorisations*.
13 1
14 13 Marc Leygnac
* Un plugin ne doit pas modifier la structure des tables GEPI, et doit, lors de sa désinstallation, replacer GEPI (tables et fichiers) dans l'état où il se trouvait lors de son installation.
15 1
16 13 Marc Leygnac
h2. Structure et contenu du fichier *plugin.xml*
17 1
18 13 Marc Leygnac
Ce fichier, obligatoirement encodé en UTF-8 (sauf s'il ne comporte que des caractères ASCII 7 bits), est lu lors de l'installation ou de la désinstallation du plugin (Gestion des modules/Gérer les plugins).
19 1
20 19 Marc Leygnac
<pre><code class="xml">
21 13 Marc Leygnac
22
<?xml version="1.0" encoding="UTF-8"?>
23
24
<gepinstall type="plugin">
25
	<!-- nom du dossier contenant les fichiers du plugin -->
26
	<nom>plugin_example</nom>
27
	<creationDate>02 2012</creationDate>
28
	<auteur>A. Turing</auteur>
29
	<licence>GNU/GPL</licence>
30
	<auteurCourriel>at@gepi.com</auteurCourriel>
31
	<auteurSite>www.at.fr</auteurSite>
32 20 Marc Leygnac
	<version>1.2</version>
33
	<versiongepi>1.7.4</versiongepi>
34 1
	<description>Plugin example</description>
35 21 Marc Leygnac
	<!-- "description_detaillee" doit décrire le traitement des données pour conformité au RGPD
36
	https://www.cnil.fr/fr/comprendre-le-rgpd  -->
37 20 Marc Leygnac
	<description_detaillee>Le plugin ne traite aucune donnée donc par défaut il est compatible RGPD.</description_detaillee>
38 13 Marc Leygnac
	<installation>
39
		<!-- requêtes SQL exécutées à l'installation du plugin -->
40
		<requetes>
41
			<requete>
42
			CREATE TABLE IF NOT EXISTS `plugin_example` (
43
			  `id_plugin_example` int(11) NOT NULL AUTO_INCREMENT,
44
			  `login` varchar(50) NOT NULL,
45
			  `nom` varchar(50) NOT NULL,
46
			  `prenom` varchar(50) NOT NULL,
47
			  PRIMARY KEY (`id_plugin_example`),
48
			  UNIQUE KEY `login` (`login`)
49
			) ENGINE=MyISAM ;
50
			</requete>
51
		</requetes>
52
	</installation>
53
	<desinstallation>
54
		<!-- requêtes SQL exécutées à la désinstallation du plugin -->
55
		<requetes>
56
			<requete>
57
			DROP TABLE `plugin_example`;
58
			</requete>
59
		</requetes>
60
	</desinstallation>
61
	<administration>
62
		<fichier>
63
		<!-- les autorisations qui suivent, portant sur le satut de l'utilisateur, peuvent être
64
		confirmées/affinées dans la fonction calcul_autorisation_plugin_example() du fichier
65
		functions_plugin_example.php -->
66
			<nomfichier autorisation="A-P-C-S-sec-autre-E-R">index.php</nomfichier>
67
			<nomfichier autorisation="A">admin.php</nomfichier>
68
			<nomfichier autorisation="A">autre_script.php</nomfichier>
69
		</fichier>
70
		<menu>
71
		<!-- liste des accès aux scripts du plugin apparaissant sur la page d'accueil et dans
72
		la barre de menu, si la fonction  calcul_autorisation_plugin_example() est définies ces
73
		accès doivent y être confirmés et éventuellement affinés -->
74 15 Marc Leygnac
			<item autorisation="A-P-C-S-sec-autre-E-R" titre="Utiliser" description="Description du script">index.php</item>
75 13 Marc Leygnac
			<item autorisation="A" titre="Administrer" description="Administration du plugin">admin.php</item>
76
		</menu>
77
	</administration>
78
</gepinstall>
79
80 19 Marc Leygnac
</code></pre>
81 13 Marc Leygnac
82
83 15 Marc Leygnac
h2. Structure d'un script PHP de plugin
84 13 Marc Leygnac
85 19 Marc Leygnac
<pre><code class="php">
86 13 Marc Leygnac
87
<?php
88 1
$niveau_arbo = "2";
89 13 Marc Leygnac
90
// Fichiers d'initialisation
91
// (attention au chemin des fichiers en fonction de l'arborescence)
92 1
include("../../lib/initialisationsPropel.inc.php");
93 9
include("../../lib/initialisations.inc.php");
94 1
include("../plugins.class.php");
95
96
// Resume session
97
$resultat_session = $session_gepi->security_check();
98
if ($resultat_session == 'c') {
99 13 Marc Leygnac
	header("Location: ../../utilisateurs/mon_compte.php?change_mdp=yes");
100 1
	die();
101
} else if ($resultat_session == '0') {
102 13 Marc Leygnac
	header("Location: ../../logout.php?auto=1");
103 1
	die();
104
}
105
106 13 Marc Leygnac
// vérification des autorisations (définies dans plugin.xml)
107
$user_auth = new gepiPlugIn("plugin_example");
108 1
$user_auth->verifDroits();
109 9
110 1
111 13 Marc Leygnac
//**************** EN-TETE *****************
112
$titre_page = "Titre de la page";
113
require_once("../../lib/header.inc");
114
//**************** FIN EN-TETE *************
115 1
116 13 Marc Leygnac
?>
117 1
118 13 Marc Leygnac
// code PHP du script
119
// ...
120 1
121 13 Marc Leygnac
<?php
122
include("../../lib/footer.inc.php");
123
?>
124 1
125 19 Marc Leygnac
</code></pre>
126 1
127 15 Marc Leygnac
h2. Le script functions_....php
128 1
129 15 Marc Leygnac
Un plugin peut contenir un script *functions_nom_du_plugin.php* (où 'nom_du_plugin' est le nom défini dans *plugin.xml*) dans lequel on peut définir les fonctions suivantes.
130 1
131 13 Marc Leygnac
h3. Fonction calcul_autorisation_...()
132 1
133 15 Marc Leygnac
Cette fonction, dont le nom doit être de la forme *calcul_autorisation_nom_du_plugin*, attend deux paramètres : un login utilisateur et le nom d'un script du plugin (avec ou non le chemin d'accès). En fonction du résultat qu'elle renvoie l'utilisateur connecté aura, sur sa page d'accueil et dans la barre de menu, accès ou non au script. Cette fonction ne prend pas en compte le chemin d'accès aux scripts, donc si le plugin contient des sous-dossiers il faut veiller à ce que les noms des scripts passés en paramètre soient distincts.
134 1
135 13 Marc Leygnac
Exemple :
136 1
137 19 Marc Leygnac
<pre><code class="php">
138 1
139 13 Marc Leygnac
function calcul_autorisation_plugin_example($login,$chemin_script)
140
	{
141
	$script=basename($chemin_script);
142
	switch ($script)
143
		{
144
		// Dès lors que la fonction calcul_autorisation_... est définie
145
		// il faut y confirmer les autorisations définies dans plugin.xml
146
		// (ou les affiner) pour les scripts devant être accessibles
147
		// depuis la page d'accueil et depuis la barre de menu.
148
		// Ici tous les utilisateurs ont accès à index.php
149
		case "index.php":
150
			return true;
151
			break;
152
		// Ici seul l'administrateur ayant installé le plugin peut l'administrer
153
		case "admin.php":
154
			return ($_SESSION['login']==getSettingValue("admin_plugin_example"));
155
			break;
156
		default:
157
			return false;
158
		}
159
	}
160 9
161 19 Marc Leygnac
</code></pre>
162 9
163 13 Marc Leygnac
h3. Fonctions ante_installation...(), post_installation...(), ante_desinstallation...(), post_desinstallation...()
164 9
165 15 Marc Leygnac
Ces fonctions, quand elles sont définies, sont exécutées respectivement avant et après "installation", avant et après "désinstallation" du plugin. Elles doivent retourner un chaîne vide si leur exécution s'est correctement déroulée, ou une chaîne contenant un message d'erreur qui sera affiché au début de la page de gestion des plugins. Si une erreur se produit à l'exécution de ante_installation...() ou de ante_desinstallation...() alors il n'est pas procédé à l'installation ou la désinstallation du plugin.
166 9
167 13 Marc Leygnac
Exemple :
168 1
169 19 Marc Leygnac
<pre><code class="php">
170 1
171 13 Marc Leygnac
function post_installation_plugin_example()
172
	{
173
	if (saveSetting("admin_plugin_example",$_SESSION['login'])) return "";
174
		else return "Impossible d'enregistrer dans la table 'setting'";
175
	}
176 1
177 13 Marc Leygnac
function post_desinstallation_plugin_example()
178
	{
179
	if (mysql_query("DELETE FROM `setting` WHERE `NAME`='admin_plugin_example'")) return "";
180
		else return "Impossible de supprimer dans la table 'setting' : ".mysql_error();
181
	}
182 10 Julien Jocal
183 19 Marc Leygnac
</code></pre>
184 10 Julien Jocal
185 15 Marc Leygnac
h2. Plugins, page d’accueil et barre de menu
186 10 Julien Jocal
187 15 Marc Leygnac
Les utilisateurs ont accès au script d'un plugin, en fonction des autorisations définies dans le fichier *plugin.xml* et éventuellement dans la fonction *calcul_autorisation_...()*, par des liens sur la page d'accueil ou dans la barre de menu. Les intitulés de ces liens sont définis dans  le fichier *plugin.xml* : description du plugin dans la section <description>, et pour chaque script titre et description dans la section <menu>.
188 10 Julien Jocal
189 15 Marc Leygnac
Sur la page d'accueil l'utilisateur trouve un cadre avec la description du plugin, puis pour chaque script son titre (support du lien) et sa description.
190 10 Julien Jocal
191 13 Marc Leygnac
Pour la barre de menu deux possibilités :
192 15 Marc Leygnac
* si l'utilisateur n'a accès qu'à un seul script alors dans le menu Plugins il trouve un lien dont l'intitulé est la description du plugin, et dont un survol par la souris fait apparaître la description du script ;
193 1
* si l'utilisateur a accès à plusieurs scripts alors de le menu Plugins il trouve une entrée dont l'intitulé est la description du plugin et dont le survol par la souris déroule un sous-menu. Ce sous-menu est composé des liens vers chaque script, liens dont l'intitulé est le titre du script et dont un survol par la souris fait apparaître la description du script.
194 10 Julien Jocal
195 21 Marc Leygnac
h2. Adapter un plugin codé pour une version antérieure à Gepi 1.6.4
196 10 Julien Jocal
197 17 Marc Leygnac
Avec la version 1.6.4 Gepi fonctionne désormais avec l'api *mysqli* alors que les versions précédentes passaient par l'api *mysql*. Donc pour adapter un plugin à cette nouvelle version de Gepi tous les appels aux fonctions mysql_*() doivent être convertis. Pour cela on peut utiliser l'outil *MySQLConverterTool* disponible sur "wikis.oracle.com":https://wikis.oracle.com/display/mysql/Converting+to+MySQLi. C'est un script PHP qui peut être  exécuté sur un serveur web ou en ligne de commande.
198
199
Sur un serveur web, près avoir copié le dossier du plugin à sa racine (ce n'est pas un nécessité, mais une commodité) il faut procéder ainsi :
200
* exécuter le script http://.../MySQLConverterTool/ , choisir l'option 'Convert a directory' puis dans la boîte de dialogue obtenue indiquer le chemin absolu vers le dossier du plugin, les extensions des fichiers à convertir, opter pour une modification des fichiers sans sauvegardes et lancer la conversion
201
!MySQLConverterTool.png!
202
* ensuite il faut dans tous les fichiers du plugin contenant du code PHP remplacer toutes les occurrences de $GLOBALS["___mysqli_ston"] par $GLOBALS["mysqli"] (ou plus simplement par $mysqli mais dans ce cas il faut ajouter "global $mysqli ;" à toutes les fonctions contenant des appels à l'api mysqli)
203 18 Marc Leygnac
* remplacer également toutes les occurrences de
204
  ((is_object($GLOBALS["mysqli"])) ? mysqli_error($GLOBALS["mysqli"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)
205
  par mysqli_error($GLOBALS["mysqli"]
206 17 Marc Leygnac
* enfin  il faut dans tous les fichiers du plugin contenant du code PHP remplacer toutes les occurrences de mysql_result par old_mysql_result
207
208
Il 'y a pas d'équivalent à la fonction mysql_result() dans l'api mysqli aussi une fonction old_mysql_result() a été ajoutée à Gepi 1.6.4 pour y pallier, mais le mieux est encore d'adapter le code, par exemple un appel (cas le plus courant) comme
209
> @$var=mysql_result($resultat,0,'champ') ;@
210
pourra être remplacé par
211
> @$t_var=mysqli_fectch_assoc($resultat) ;@
212
> @$var=$t_var['champ'] ;@
213
214 16 Marc Leygnac
h2. Des idées de plugins
215 10 Julien Jocal
216 15 Marc Leygnac
Ce n'est pas ce qui manque :
217
* la page blanche du PP pour chacun de ses élèves ;
218
* intégrer du code pour initialiser GEPI à partir d'un ENT (ou de toute autre source externe) ;
219
* un lieu de réunion pour chaque équipe éducative qui pourrait ainsi laisser des infos avant un conseil ou pour aider celui qui prépare le conseil de classe ;
220
* un tchat d'échange entre professeurs ;
221
* et bien d'autres idées, laissez vous aller :)
222 14 Marc Leygnac
223
h2. Un exemple pour tout comprendre :
224 17 Marc Leygnac
225
Télécharger ci-dessous le plugin *plugin_example* et examiner son code.
226
227
----
228
229
----