Articles

  Création de A à Z d'un module pour NK (schéma général)
Catégorie : Nuked klan -> Messages d'erreurs
Ajouté le : 28.06.2008 15:15
Auteur : Paolo76
Lectures : 181
Commentaires : 0 [ Poster un commentaire ]
Note : Non évalué [ Evaluer ]

Création de A à Z d'un module pour NK (schéma général)

Introduction

Avant d'aborder ce tuto, il est fortement conseiller de connaitre un minimum le PHP (ou du moins les principes de base de la programmation), en effet je ne vais pas passer mon temps à vous apprendre à programmer, là n'est pas le but et il existe pleins de tuto très bien fait qui vous l'explique mieux que moi. Précision :

Quand je parle d'utilisateur, je fais référence aux visiteurs et membres confondu.
Quand je parle d'inclusion ou xxx inclut yyy je fait référence à la fonction include(); de PHP.
Prenons “index.php?file=User” comme URI : file est appelé paramètre, et [User] la valeur du paramètre.
Faites attention à ne pas confondre [valeur du paramètre] et le paramètre lui même.
Légende : [Valeur param] | Paramètre | Morceau de l'URI


Fonctionnement général

Avant de parler précisément de création de module, voyons d'abord comment cela fonctionne de manière générale. Le liens (que j'appelerais URI) pour accéder au module est sous la forme : index.php?file=Votremodule&page=index (notez que l'argument page et sa valeur [index] ne sont pas obligatoires pour accéder à la page principal d'un module mais cela nous servira dans la suite du tutorial). Voyons plus en détails ce que représente cette URI, afin d'en comprendre son fonctionnement.

Le fichier principal du CMS : index.php

Tout d'abord, on constate la présence de index.php au début de notre URI (index.php?file=Votremodule&page=index). Il s'agit de l'index.php de Nuked-Klan, celui qui se trouve à la racine de votre site. C'est lui qui charge la page de connection à la base de données et les fichiers principaux tel que nuked.php et globals.php, qui vérifie la validité des sessions, le bannissement, gère les thèmes, le status de votre site (ouvert/en construction par exemple) et l'inclusion des différents modules (que nous allons voir en détails). Il est donc le fichier central, le noyau, du CMS Nuked-Klan et c'est pour cela qu'il est utilisé à chaque fois que vous changez de page.

Le système d'inclusion des modules

Continuons notre analyse de l'URI : on peut voir ?file= qui succède index.php. Le point d'interrogation permet simplement de limiter le nom du fichier (index.php) du reste des données contenues dans l'URL (file=Votremodule&…). [La valeur du paramètre file], qui se trouve juste après le signe égal (dans notre cas [Votremodule]), est en fait le nom du dossier situé dans le répertoire /modules/ de NK. En effet, c'est le système d'inclusion des modules (je l'appelerais SIM) de NK qui est construit de cette façon. Il inclu [la valeur de file] et l'exécute : l'arborescence pour atteindre notre module peut donc être représentée ainsi : /modules/[Votremodule]/. L'inclusion utilisé dans le SIM se fera donc comme ceci : include('/modules/Votremodule/'); .

“Oui mais là tu inclus un répertoire et pas un fichier, ça fonctionnera jamais !”.
En effet, et c'est ici qu'intervient la valeur du second argument nommé page situé après file=Votremodule dans notre URI d'exemple.
Je vous explique : tout d'abord, le SIM va recherché [la valeur du paramètre page] (qu'on appelera [$im_file]), dans l'URI. Si celle-ci n'existe pas ou qu'elle est vide, [$im_file] prendra la valeur de “index”. Dans notre exemple, [$im_file] sera égal à “index” car dans l'URI, page=[index]. L'inclusion se fait comme ceci :



Code :
include('/modules/Votremodule/'.$im_file.'.php');



Code :
//Ligne 53 - index.php
if (isset($nuked_nude) && $nuked_nude != "") $im_file = $nuked_nude; //$nuked_nude ne sera pas expliqué dans ce tuto, renseignez-vous ailleurs pour aller plus loin.
else if (isset($page) && $page != "") $im_file = $page; //$page est la var globale qui correspond à la valeur de l'argument page dans l'URI, autrement dit "index" dans notre exemple.
else $im_file = "index"; //Si $page n'est pas précisé alors $page = "index".

//Ligne 110 - index.php
if(is_file("modules/" . $file . "/" . $im_file . ".php")) //Vérifie que le fichier a inclure existe et que c'est bien un fichier.
{
include("modules/" . $file . "/" . $im_file . ".php");
}
else
{
include("modules/404/index.php"); //Sinon on affiche la page d'erreur indiquant que le module ou l'adresse n'existe pas


Les plus futés d'entre vous auront remarqué qu'ils peuvent donc scinder leur module en plusieurs fichiers et les appeler de cette manière. C'est le cas pour le fichier admin.php contenu dans la plupart des modules, qui est appelé comme ceci : index.php?file=Votremodule&page=admin où admin correspond à /modules/Votremodule/admin.php biensur.

Les différentes pages d'un module

Maintenant qu'on sait comment fonctionne l'inclusion d'un module, on va s'attaquer à son contenu et ses fichiers qui le composent. De manière générale donc, tous les modules comportent au minimum un fichier index.php et admin.php (il existe des exceptions biensur) ainsi qu'un répertoire lang/ contenant les deux fichiers principaux pour la traduction (la version anglaise et française). Ces deux fichiers de langues sont appelés au début des fichiers PHP du module. Voici comment les mettres en place :


Code :
global $language; //Cette variable globale contient la langue du site (la langue du site est paramétrable dans les préférences générales de l'administration)
translate("modules/Votremodule/lang/" . $language . ".lang.php"); //Si vous désirez en savoir plus, la fonction translate() est créée dans le fichier nuked.php


Pour faire simple, la fonction translate() inclut le fichier de langue correspondant à la langue du site, et transforme toutes les variables de langues (ex : _NOENTRANCE défini/traduit différement selon le fichier langue utilisé).
N'oublier jamais d'utiliser la balise <?php et non <? pour tous vos scrips PHP ainsi que dans les fichiers french.lang.php et pour les autres langues, sinon cela peut engendrer une mauvais fonctionnement sur certains hébergeurs).
Revenons-en à nos fichiers, l'index.php est le fichier visible par les utilisateurs et le fichier admin.php par les administrateurs, c'est logique.

Quoi ? J'ai juste à nommer mon fichier admin.php pour que les visiteurs et les membres n'y aient pas accès ?
Et bien non ! Comme on l'a vu plus haut, rien n'empèche de changer le nom des fichiers du module puisqu'ils sont juste passés dans la valeur du paramètre page, ce n'est donc pas ça qui garantit la sécurité du module. C'est pourquoi il faut mettre en place un système de gestion d'accès.


Le système de gestion des accès

Sans trop rentrer dans les détails en ce qui concerne la sécurité du CMS, il faut savoir que tous les modules comportent une en-tête bien spécifique. Celle-ci permet d'empècher l'exécution de pages PHP qui ne nécessitent pas l'index.php, car c'est lui qui possède aussi les fonctions de protections de NK comme expliqué tout au début. Chaque fichier de votre module devra donc comporter cette en-tête ainsi que l'en-tête de la licence GNU GPL :


Code :
if (!defined("INDEX_CHECK"))
{
die ("<div style=\\"text-align: center;\\">You cannot open this page directly</div>");
}


Voici un petit récapitulatif de votre fichier index.php :


Code :
<?php
//-------------------------------------------------------------------------------------------- //
// Nuked-KlaN - PHP Portal //
// http://www.nuked-klan.org //
//-------------------------------------------------------------------------------------------- //
// 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. //
//-------------------------------------------------------------------------------------------- //
if (!defined("INDEX_CHECK"))
{
die ("<div style=\\"text-align: center;\\">You cannot open this page directly</div>");
}

global $nuked, $language, $user; //Attention à ne pas oublier $nuked et $user comme variable global, nous en auront besoin plus loin
translate("modules/Votremodule/lang/" . $language . ".lang.php");

?>


Passons à la gestion des accès à proprement parler.

Que doit-on faire exactement ?
Plusieurs choses.
La première c'est de vérifier le niveau de l'utilisateur qui tente d'afficher votre module.
La deuxième chose c'est de regarder le niveau d'accès à ce module (c'est l'admin principal qui choisit).
Ensuite il faut comparer les deux et soit lui afficher le contenu du module, ou bien renvoyer un message d'erreur en indiquant qu'il n'a pas les droits nécessaire pour l'afficher si tel est le cas.
Et ceci n'est pas très compliqué. En effet Nuked-Klan possède des fonctions qui permettent d'obtenir rapidement le niveau nécessaire à un utilisateur pour l'affichage du module, nivo_mod() et admin_mod() (créées dans le fichier nuked.php), et une variable globale, nommée $user, qui contient plusieurs informations sur la personne qui tente d'accéder au module, dont son niveau, qu'on obtiendra de cette manière : $user[1] (ex : si l'admin principal va sur votre module, $user[1] sera égal à 9).
Bon voila avec toutes ces infos on peut facilement programmer la gestion des accès. En voici un exemple assez complet et commenté :



Code :
if(!$user) $visiteur="0"; //Si la variable globale n'existe pas alors c'est un visiteur
else $visiteur=$user[1]; //Sinon on enregistre le level de l'utilisateur dans la variable $visiteur
$ModName = basename(dirname( __FILE__ )); //Permet de connaitre le répertoire courant. Dans notre exemple $ModName = "Votremodule"
$level_access = nivo_mod($ModName); //On utilise la fonction nivo_mod pour recherché dans la bdd le level nécessaire à l'utilisateur pour pouvoir afficher le module "Votremodule".
if ($visiteur>=$level_access && $level_access > -1) //Si le level d'accès est suffisant et que le module n'est pas désactivé, on accepte
{
//Affichage du module (on va voir juste après ce qu'il faut mettre ici)
}
else if ($level_access == -1) //Si le module est désactivé
{
opentable();
echo'<br /><br /><div style="text-align: center;">'._MODULEOFF .'<br /><br /><a href="javascript:history.back()"><strong>'._BACK .'</strong></a><br /><br /></div>';
closetable();
}
else if ($level_access == 1 && $visiteur == 0) //Si le niveau nécessaire est 1 (membre) et que l'utilisateur est un visiteur (niveau 0) alors on lui dit qu'il faut être enregistré pour avoir accès
{
opentable();
echo '<br /><br /><div style="text-align: center;">'._USERENTRANCE .'<br /><br /><strong><a href="index.php?file=User&amp;op=login_screen">'._LOGINUSER .'</a> | <a href="index.php?file=User&amp;op=reg_screen">'._REGISTERUSER .'</a></strong><br /><br /></div>';
closetable();
}
else //Sinon c'est qu'il n'a pas du tout accès (le module n'est visible que par les admins)
{
opentable();
echo '<br /><br /><div style="text-align: center;">'._NOENTRANCE .'<br /><br /><a href="javascript:history.back()"><strong>'._BACK .'</strong></a><br /><br /></div>';
closetable();


Cette portion de code se met à la suite de ce que nous avons déjà programmer.

Là où nous en sommes, vous aller me dire “Oui c'est bien beau tout ça mais il n'y a rien qui s'affiche quand j'essaye d'accéder à mon module”.
C'est tout à fait normal on a laisser vide à l'endroit où ça devrait être rempli.
Que faut-il donc mettre à cet endroit ?
Nous allons mettre deux choses différentes à cet endroit. Lisez la suite.


Les fonctions et leurs appels

Dernière partie de ce tutorial qui va vous expliquer comment on appel ses fonctions qui affichent le contenu de votre module et l'endroit où on les places.

Il y a plusieurs façon possibles pour utiliser ses fonctions dans un module, mais nous verons la plus courante.
- En cours de rédaction -


Créer un fichier d'installation

Voici une petite section complémentaire pour vous expliquer comment on créé un fichier d'installation.

Mais pour cela il faut se poser la question de savoir à quoi ça sert un fichier d'install et dans quelles conditions en a-t-on besoin ?
Le fichier d'installation (souvent appelé install.php, je vous laisser deviner pourquoi :D), permet en fait et de manière générale, d'exécuter des requètes SQL, si votre module nécessite une ou plusieurs nouvelles tables pour stocker les informations relatives à celui-ci. Imaginons qu'il n'existe pas de module Livre d'Or, nous avons besoin de créer les tables pour enregistrer les messages envoyés par les utilisateurs. Un exemple commenté d'installation pour un module Livre'Dor vaut mieux qu'un long discours :D




Code :
<?php
//-------------------------------------------------------------------------------------------- //
// Nuked-KlaN - PHP Portal //
// http://www.nuked-klan.org //
//-------------------------------------------------------------------------------------------- //
// 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. //
//-------------------------------------------------------------------------------------------- //

if (is_file('nuked.php'))
{
include('nuked.php'); //On vérifie que le fichier install.php se trouve au bon endroit et on inclut nuked.php afin de pouvoir utiliser la variable globale $nuked
include('Includes/version.php'); //Permet d'utiliser la variable $nk_version pour par exemple tester si la version est la bonne
}
else die('<br /><br /><div style="text-align: center; font-weight:bold;">The file install.php must be near nuked.php</div>'); //Sinon on affiche une erreur (la fonction die() permet de stopper l'execution totale de la suite du script et d'afficher un message d'erreur).


function style() //Permet de choisir le style de la page sans utiliser de feuille de style supplémentaire
{
/*En-tête du document
<html>
<head>
<title></title>
<style>div{border:1px solid red;} ...</style>
</head>
<body>
*/
}

//### Affichage de l'installation ###
function index()
{
global $nuked;
style(); //On utilise l'en-tête précédemment créée

//Vérification si INSTALLATION ou RÉINSTALLATION du module afin de ne pas dupliquer le liens dans l'admin
$test = mysql_query("SELECT id FROM " . $nuked['prefix'] . "_modules WHERE nom='**LivreDor**'");
$req = mysql_num_rows($test); //On compte le nombre de résultat obtenu
if($req == 1) //Si 1 résultat --> le module existe déjà
{
//Action à faire dans ce cas. Par exemple afficher un message d'erreur ou une variable contenant un message pour avertir l'utilisateur
}

echo'<input type="button" name="Yes" onclick="document.location.href=\\'install.php?**op=update**\\';" value="Install">
<input type="button" name="No" onclick="document.location.href=\\'install.php?**op=nan**\\';" value="Don\\'t install">'; //Ici vous affichez ce qui apparaitra lorsque l'utilisateur arrivera dans install.php (n'oublier pas de fermé les balises HTML </body></html>)
}

//## Si l'utilisateur clique sur "OK" et valide l'installation
function update()
{
global $nuked;
style();

// !!! Efface les tables si déjà existantes (n'oublier pas d'informer l'utilisateur que s'il souhaite quand même procédé à l'installation, cela va supprimer les tables correspondantes au module)
(Vous pouvez supprimer ces lignes si vous ne souhaitez pas vider les tables au cas ou elle existeraient déjà)
mysql_query("DROP TABLE IF EXISTS ". $nuked['prefix'] ."_livredor_config");
mysql_query("DROP TABLE IF EXISTS ". $nuked['prefix'] ."_livredo_message");

//Création de la table "livredor_message"
$sql = "CREATE TABLE ". $nuked['prefix'] ."_projets (
`id` int(11) NOT NULL auto_increment,
`titre` text NOT NULL,
`message` text NOT NULL,
`auteur` text NOT NULL,
`date` int(11) NOT NULL default '0',
PRIMARY KEY (`id`)
)";
mysql_query($sql); //On execute la requète contenue dans la variable $sql

//Création de la table "livredo_config"
$sql = "CREATE TABLE ". $nuked['prefix'] ."_livredor_config (
`nom` varchar(255) NOT NULL,
`value` text NOT NULL,
PRIMARY KEY (`id`)
)";
mysql_query($sql); //On execute la requète contenue dans la variable $sql ($sql vient d'être modifié)

//Ajouter des données dans les tables que vous venez de créer
mysql_query("INSERT INTO ". $nuked['prefix'] ."_livredor_config VALUES ('max_message', '50')");
mysql_query("INSERT INTO ". $nuked['prefix'] ."_livredor_config VALUES ('captcha', '1')");

//Vérification si INSTALLATION ou REINSTALLATION du module afin de ne pas dupliquer le liens dans l'admin
$test = mysql_query("SELECT id FROM " . $nuked['prefix'] . "_modules WHERE nom='LivreDor'");
$req = mysql_num_rows($test);
//Ajout du liens dans le panel d'administration s'il n'existe pas.
if($req == 0)
{
$sql = mysql_query("INSERT INTO " . $nuked['prefix'] . "_modules (id, nom, niveau, admin) VALUES ('', 'LivreDor', 0, 2);");
//niveau représente le niveau minimum pour avoir accès au module, et admin le niveau pour voir accès à l'administration du module
}

//On termine l'installation en affichant un message
echo '<br /><br /><div style="text-align: center; font-weight:bold;">Module Livredor installed successfully.<br /><br />Redirection...</div>';
//Suppression automatique du fichier install.php (le @ permet de ne pas afficher d'erreur en cas de non-succès de la fonction unlink dans ce cas. Certains hébergeur ont désactivé cette fonction. Il faut donc avertir l'utilisateur en lui demandant de supprimé l'install.php manuellement)
if(@!unlink("install.php"))
{
echo'<br /><br /><div style="text-align: center;">Please remove install.php from your FTP</div>';
}
redirect("index.php", 3);
}
//### Si l'utilisateur ne désire pas installer le module.
function nan()
{
style();

echo '<br /><br /><div style="text-align: center; font-weight:bold;">Install canceled...</div>';
redirect("index.php", 3);
}

//Notre switch comme vu précemment dans la section 'Les fonctions et leurs appels'
switch($op)
{
case"index":
index();
break;

case"update":
update();
break;

case"nan":
nan();
break;

default:
index();
break;
}
?>Je tiens à préciser que cette installation ne fonctionne pas tel


:ouf: a vous ! :ptdr:

  

Informations | Mes Partenaires | Plan du site | Publicité
Copyright 2008-2009 Best-Nk.fr et Best-Creative.fr powered by Nuked-Klan
Design by Web-Grafx.Com et Codé par Best Group
Les images, le codage et le contenu sont la propriété de Best Group,
il est strictement interdit de le copier sans autorisation.