Créer un module

La création d’un module est assez simple. Toutefois, pour des raisons d’organisation, la création de modules a des contraintes, notamment pour nommer les tables qu’il utilise dans la base de données.

Le code de base d'un module

Voici le code de base d’un module. J’ai pris pour exemple le minichat (minichat.php). Il est sufisemment commenté pour que vous puissiez le comprendre ;-) .

Note : La création d’un module est assez contraigante, car il faut pouvoir gérer le module depuis l’interface d’administration, et éviter les conflits entre les modules. C’est pour cela qu’il faut respecter quelques conventions de nommage.

<?php
/*
 
Copyright (C) <Annee> <Nom> <Prenom>
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 
NB : Les modules que vous créez doivent être sous licence GPL.
*/
 
//code fixe
require('include/common.php');
$module = array('nom' => 'Minichat', 'prefix' => 'minichat', 'options' => '0');
/*
L'array $module doit contenir :
-Le nom de votre module, celui qui sera visible par les membres,
-Le préfixe de votre module. Ce préfixe est en fait le nom du fichier de votre module sans l'extension.
-Enfin, options vaut 0 s'ils n'y a pas d'options, 1 s'il y en a (pas d'utilisation de booléen car cette valeur va être entrée dans la BDD)
*/
 
//On vérifie que le membre est connecté.
if (isset($_SESSION[$prefix.'logged']) && $_SESSION[$prefix.'logged'] === true)
{
	if($_SESSION[$prefix.'admin'] == 1 AND isset($_GET['admin_action']))//Options d'administration du module
	{
		if($_GET['admin_action'] == 'installer')//confirmation d'installation. Il faut afficher un message d'avertissement.
		{
			 echo stop('Vous vous appr&ecirc;tez &agrave; installer le module '.$module['nom'].'.<br />Les modules ne sont ni officiels, ni pris en charge par kankanSpace.<br /><a href="'.$module['prefix'].'.php?admin_action=installer_confirme">Je confirme l'installation</a>', '');
			 //Note : si vous modifiez une table du kankanSpace "de base", c'est ici qu'il faut le signaler.
		}
		elseif($_GET['admin_action'] == 'installer_confirme')//code d'installation
		{
			//si ce module à besoin de tables particulières, on les crées (éventuellement une table pour le stockage des options)
			mysql_query('CREATE TABLE `'.$prefix.$module['prefix'].'` (`id` int(11)  NOT NULL AUTO_INCREMENT, `pseudo` varchar(255) NOT NULL, `message` text NOT NULL, KEY `id` (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;');
			
			//dans tous les cas, on le déclare dans la table des modules (si l'array est correctement rempli, cette requête n'est pas à modifier)
			mysql_query('INSERT INTO '.$prefix.'modules(fichier, nom, options, date_installation, membre_installateur) VALUES (''.$module['prefix'].'.php', ''.$module['nom'].'', '.$module['options'].', '.time().', '.$_SESSION[$prefix.'id'].')');
			
			//insertion des liens(même chose, en principe, l'on a pas besoin de toucher à cette requete)
			mysql_query('INSERT INTO '.$prefix.'liens(texte, adresse, visible_membres, apparaitre_menu) VALUES (''.$module['nom'].'', ''.$module['prefix'].'.php', 1, 1)');
			
			//affichage du message de confirmation
			echo stop('Le module '.$module['nom'].' a bien &eacute;t&eacute; install&eacute;.', $module['prefix'].'.php');
			
		}
		elseif($_GET['admin_action'] == 'desinstaller')//confirmation de désinstallation : on affiche un message
		{
			 echo stop('Vous vous appr&ecirc;tez &agrave; d&eacute;sinstaller le module '.$module['nom'].'.<br />La d&eacute;sinstalaltion d`un module est irr&eacute;versible.<br /><strong>Il est fortement conseill&eacute; de sauvegarder votre base de donn&eacute;es avant de proc&eacute;der &agrave; la d&eacute;sinstalation de ce module.</strong><br /><a href="'.$module['prefix'].'.php?admin_action=desinstaller_confirme">Je confirme la d&eacute;sinstallation</a>', 'admin_modules.php');
		}
		elseif($_GET['admin_action'] == 'desinstaller_confirme')//code de désinstallation
		{
			//suppression des tables du module
			mysql_query('DROP TABLE '.$prefix.$module['prefix']);
			
			//suppression de l'entrée dans la table module
			mysql_query('DELETE FROM '.$prefix.'modules WHERE fichier=''.$module['prefix'].'.php'');
			
			//suppression des liens
			mysql_query('DELETE FROM '.$prefix.'liens WHERE adresse=''.$module['prefix'].'.php'');
			
			//message de confirmation
			echo stop('Le module '.$module['nom'].' a bien &eacute;t&eacute; d&eacute;sinstall&eacute;.', 'admin_modules.php');
		}
		else//Options du module (s'il en a)
		{
			designhaut('Options - '.$module['nom']);
			//Si vous avez des options, c'est ici qu'il faut les mettre. Il n'y a pas de convention. Je vous conseille toutefois de renvoyer le formulaire vers la page du module avec le paramètre admin_action=options et de vérifier si le formulaire est rempli.
			designbas();
		}
	}
	else//si ce n'est pas une option d'administration, code normal.
	{	
		designhaut($module['nom']);
	
		//A partir de maintenant, à vous de jouer !
		
		echo '<h1>'.$module['nom'].'</h1><strong><a href="'.$module['prefix'].'.php">Actualiser</a></strong>';
		
		//suppression d'un message (si l'on est admin)
		if($_SESSION[$prefix.'admin'] == 1 AND isset($_GET['action'], $_GET['id']) AND $_GET['action'] == 'supprimer' AND !empty($_GET['id']))
		{
			$id = intval($_GET['id']);
			
			mysql_query('DELETE FROM '.$prefix.$module['prefix'].' WHERE id='.$id);
			
			echo '<h2>Suppression du message :</h2>Le message '.$id.' a bien &eacute;t&eacute; supprim&eacute;.';
		}
		
		if (isset($_POST['pseudo'], $_POST['message']) AND !empty($_POST['pseudo']) AND !empty($_POST['message'])) // Si les variables existent
		{
			$message = mysql_real_escape_string(htmlentities($_POST['message']));
			$pseudo = $_SESSION[$prefix.'pseudo'];
 
        		mysql_query('INSERT INTO '.$prefix.$module['prefix'].' VALUES('', ''.$pseudo.'', ''.$message.'')');
		}
?>
<h2>Entrez un message :</h2>
<div class="centre">
 
<form action="minichat.php" method="post">
 
<p>
<input type="hidden" name="pseudo" value="<?php echo $_SESSION[$prefix.'pseudo']; ?>"/><br />
Message :  <input type="text" name="message" tabindex="1" /><br />
 
<input type="submit" value="Envoyer" tabindex="2" />
</p>
 
</form>
</div>
<br />
<h2>Messages post&eacute;s :</h2>
<div class="chat">
<?php
		$reponse = mysql_query('SELECT id, pseudo, message FROM '.$prefix.$module['prefix'].' ORDER BY id DESC LIMIT 0,10');
 
		while ($donnees = mysql_fetch_array($reponse) )
		{
			echo '<p><strong>'.$donnees['pseudo'].'</strong> : '.$donnees['message'];
 
			if ($_SESSION[$prefix.'admin'] == 1)
			{
				echo '<br /><a href="'.$module['prefix'].'.php?action=supprimer&amp;id='.$donnees['id'].'">Supprimer</a>';
			}
?></p>
<?php
		}
 
		// Requête pour savoir le dernier message à garder. On garde 20 messages, mêmes si il y a seulement 10 messages d'affichés pour éviter d'avoir  moins de dix messages affichées en cas de suppression.
		$message_a_supprimer = mysql_query('SELECT id FROM '.$prefix.$module['prefix'].' ORDER BY id DESC LIMIT 20,1') or die(mysql_error());
 
		$a_supprimer = mysql_fetch_array($message_a_supprimer);
 
		$id_du_message_a_supprimer = $a_supprimer['id'];
 
		if ($id_du_message_a_supprimer != NULL) //si l'ID du message 
		{
			mysql_query('DELETE FROM minichat WHERE id<='.$id_du_message_a_supprimer) or die(mysql_error());
		}
 
		echo '</div>';
		//Code fixe de nouveau, pour terminer les conditions du début et afficher le pied de page
		designbas();
	}
}
else
	header('location: index.php');
?>

Note : Avant de copier/coller bêtement le code, je précise qu’il y a un bug sur DokuWiki, qui fait disparaître les antishlashes. Il faut donc bien tout vérifier, pour éviter de se retrouver avec des parse errors. En cas de doute, prenez comme modèle le code du minichat de votre installation. Il y a juste quelques commentaires en moins, c’est tout ;-) .

Règles pour la création de modules publics

Je sais, avoir ces règles est un petit peu pénible, mais nécéssaire pour éviter que l’installation d’un module par un utilisateur de kankanSpace ne se transforme en cauchemar. Voici donc quelques règles à respecter :

  • Essayez de n’avoir qu’un seul fichier dans la mesure du possible.
  • Le nom de ce fichier devra ressembler au nom de votre module (évitez les majuscules, les espaces et autres caractères spéciaux).
  • Essayez de ne pas modifier fondamentalement le code de base.
  • Remplissez l’array $module avec des valeurs cohérentes. Le préfixe doit-être le nom de fichier sans extension.
  • Lors de l’installation, pensez bien à ajouter un enregistrement dans la tables modules.
  • Si vous utilisez des tables dans MySQL, utilisez le préfixe de kankanSpace ($prefix), suivi du préfixe de votre module ($module[’prefix’]), puis éventuellement un nom si vous utilisez plusieurs tables.
  • Évitez de modifier les tables du kankanSpace “classique”. Si cela est vraiment nécéssaire, informez-en vous utilisateurs lors de l’installation et effacez ces modifications lors de la désinstallation du module.
 
creer_un_module.txt · Dernière modification: 29/04/2008 09:53 par kankan
 
Ce wiki est sous licence CC BY-SA