[3.0.x] Utiliser les sessions de phpBB

Rédigé le: 02 Nov 2008 à 16:39
- Utiliser les sessions de phpBB

Ce tutoriel a pour but de vous familiariser avec l'emploi des sessions phpBB, ceci afin de vous permettre, dans votre site perso, extérieur à phpBB de garder la connexion de vos utilisateurs enregistrés et d'utiliser les styles de mise en page de phpBB

Sommaire
  1. Le script de base
  2. Créer un formulaire de connexion
    1. version de base
    2. version templatée
  3. Enregistrer de nouveaux utilisateurs à partir de votre site
    1. version de base
    2. version templatée
  4. Exporter votre base d'utilisateurs vers phpBB
  5. Créer une page de news
    1. version de base
    2. version templatée
  6. Modifier le gestionnaire de messages d'erreurs

  7. Ajouter une captcha au formulaire de connexion
      version non templatée
support de ce tuto => ICI


1- Le script de base

Soit un fichier nommé test.php que vous mettrez dans la racine de votre site et qui, en supposant que votre forum se trouve placé dans le répertoire phpBB3, se présentera ainsi:
Code: Tout sélectionner
<?php
define('IN_PHPBB', true);
$phpbb_root_path = './phpBB3/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
$user->session_begin();
$auth->acl($user->data);
$user->setup();
?>


Explications
  • définition de la constante IN_PHPBB
    Code: Tout sélectionner
    define('IN_PHPBB', true);
    Elle est nécessaire, car afin de bloquer les accès directs au répertoire include ou à common.php, tout script qui inclurait un fichier de ce répertoire ou common php et qui n'aurait pas auparavant défini cette constante aboutirait à une page blanche.

  • définition du répertoire de phpBB
    Code: Tout sélectionner
    $phpbb_root_path = './phpBB3/';
    utilisé par phpBB pour calculer le chemin d'un script.
    cette ligne est une fréquente cause d'erreurs chez ceux qui testent ce script. vous devez calculer le chemin qui va de votre page en cours au répertoire de phpBB.
    • déjà, si votre phpBB est situé, non pas dans le répertoire phpBB mais dans le répertoire forum, il vous faut mettre à la place
      Code: Tout sélectionner
      $phpbb_root_path = './forum/';
    • si votre script se situe dans un sous répertoire de la racine et que phpBB est dans le sous-répertoire phpBB3 alors cette ligne deviendra
      Code: Tout sélectionner
      $phpbb_root_path = './../phpBB3/';

  • Définition de l'extension php du fichier
    Code: Tout sélectionner
    $phpEx = substr(strrchr(__FILE__, '.'), 1);
    tous les scripts de phpbb fonctionent avec cette extension. si vous ne la définissez pas, cela finira par une page d'erreur 404 'fichier non trouvé'.

  • inclusion de common.php
    Code: Tout sélectionner
    include($phpbb_root_path . 'common.' . $phpEx);
    common.php peut-être considéré comme le coeur de phpBB, rien de ce qui suivra ne marchera s'il n'est pas lancé, et son lancement échouera si les lignes précédentes ne sont pas incluses

  • Le lancement de la session
    Code: Tout sélectionner
    $user->session_begin();
    c'est le but ultime: lancer une session phpBB sans laquelle vous ne pouvez pas travailler avec phpBB
    il est IMPERATIF qu'aucun texte n'ait été affiché avant cette ligne, sinon, vous aurez droit à l'erreur
    Cannot modify header information - headers already sent by (output started at C:/wamp/www/singles/test.php:5)

  • les deux lignes suivantes sont facultatives
    Code: Tout sélectionner
    $auth->acl($user->data);
    $user->setup();
    • la première vérifie les autorisations de l'utilisateur (toujours utile de vérifier s'il est admin ou modo)
    • la seconde charge le thème et les langues (nécessaire, si vous envisagez d'utiliser les templates)

Et maintenant ?
une fois lancée la session, vous avez à votre disposition
  • Des données sur l'utilisateur connecté à partir du tableau $user->data qui regroupe tous les champs des tables phpbb_users et phpbb_sessions.
    • son id: $user->data['user_id']
    • son pseudo: $user->data['username']
    • Est-ce un utilisateur enregistré ? : $user->data['is_registered']
    • Est-ce un robot ? $user->data['is_bot']
  • Des informations sur la page en cours à partir de $user->page
      fichier utilisé: $user->page['page_name']
      url complète relative à la racine du forum : $user->page['page']

  • l'affichage de la date avec $user->format_date
    par exemple
    Code: Tout sélectionner
    $user->format_date( time() )
    affichera la date du jour au format de date de votre profil
    Code: Tout sélectionner
    $user->format_date( time(), 'd/m/Y' )
    l'affichera selon le format que vous aurez indiqué
  • L'accès au moteur de template, dont une instance $template a été créée (pour plus de détails, voir le tuto sur les templates
  • L'accès à la base de données: une connexion à la base de données a été créée à partir de $db
    exemples d'utilisation:
    • lancer une requête sql avec $db->sql_query (équivalent de mysql_query)
      Code: Tout sélectionner
      $result = $db->sql_query($sql);
    • lire le résultat d'une requête avec $db->sql_fetchrow (qui, contrairement à ce qu'on pourrait penser, n'est pas un équivalent de mysql_fetch_row mais un équivalent de mysql_fetch_assoc)
      Code: Tout sélectionner
      $row = $db->sql_fetchrow($result);

Précautions
  • ne perdez pas la session!
    Pour que la session puisse se propager de page en page, phpBB a besoin, au cas où les cookies ne sont pas acceptés, de connaitre l'id de session.
    pour cela, toutes les urls doivent passer par la fonction append_sid
    donc au lieu de mettre ce lien
    Code: Tout sélectionner
    echo '<a href="mapage.php">mon lien</a>';

    mettez à la place
    Code: Tout sélectionner
    echo '<a href="' . append_sid('mapage.php') . '">mon lien</a>';
  • Sécuriser les retours de variables
    Evitez autant que possible l'utilisation de $_GET et $_POST.
    Faites appel, à la place, à la fonction phpBB request_var
    par exemple, à la place de
    Code: Tout sélectionner
    $forum_id = $_GET['forum_id'];
    faites
    Code: Tout sélectionner
    $forum_id = request_var('forum_id', 0)
    indique qu'on attend une valeur numérique de valeur par défaut zéro.
    les différents types de valeur par défaut:
    • numérique:
      Code: Tout sélectionner
      $mavar = request_var('ma_var', 0 );
    • chaine:
      Code: Tout sélectionner
      $mavar = request_var('ma_var', '' );
    • tableau de valeurs numériques
      Code: Tout sélectionner
      $mavar = request_var('ma_var', array(0) );
    • tableau dont les clés sont des chaines et les valeurs des nombres
      Code: Tout sélectionner
      $mavar = request_var('ma_var', array( '' => 0 ) );
  • Variables réservées
    les variables suivantes ne doivent être utilisées qu'en lecture sous peine d'aboutir à des erreurs
    • $db
    • $user
    • $config
    • $auth
    • $template
    par exemple imaginons que vous vouliez récupérer le nom de l'utilisateur à partir de cette url portail.php?user=spitfirepat
    si vous faites
    Code: Tout sélectionner
    $user=$_GET['user']
    eh bien vous aurez détruit l'instance $user de la classe user et ça va se terminer par une erreur
la suite ?
dans les chapitres suivant nous verrons comment créer un formulaire de connexion, enregistrer un nouvel utilisateur en dehors de phpbb et créer une page de news. Tous les scripts sont présenté en deux versions: php pure et templatée. Ceci d'abord pour ne pas perturber les utilisateurs de php pur si je ne présentais qu'une version templatée (et inversement) et ensuite la comparaison des deux modèles de scripts vous permettra de voir à quel point le templating vous facilite le codage


2-a Créer un formulaire de connexion - version de base

Voilà, vous avez un site où vous avez intégré un forum phpBB et vous aimeriez bien que vos utilisateurs puissent se connecter sur le site sans avoir à passer par le forum et sans que les avis de succès ou d'echec de la tentative de connexion ne passent par le forum.
nous allons donc bâtir un script php qui va faire tout ça, que nous nommerons mon_login.php
son architecture sera la suivante:
  • si l'utilisateur est connecté nous afficherons son pseudo et un lien vers la déconnexion
  • sinon nous afficherons le formulaire
donc au démarrage du script, nous devrons avoir à gérer 2 types de retour
  • la demande de déconnexion: $_GET['logout']
  • la validation du formulaire: $_POST['login']
---------------------------------------------------------------------------------------------------------------------
  • La première chose à vérifier est la demande de déconnexion: dans ce cas, on détruit la session en cours, et on redémarre une nouvelle session
    Code: Tout sélectionner
    if (isset($_GET['logout']))
    {
    	$user->session_kill();
    	$user->session_begin();
    }
  • ensuite on vérifie s'il n'y a pas eu de validation du formulaire. dans ce cas on aura des variables $_POST login, username, password, autologin et viewonline
    on ajoute une variable $admin qu'on mettra à zéro, parce que nous ne sommes pas en train d'accéder au panneau d'administration
    Code: Tout sélectionner
    if (isset($_POST['login']))
    {
    	$username = request_var('username', '', true);
    	$password    = request_var('password', '', true);
    	$autologin   = (!empty($_POST['autologin'])) ? true : false;
    	$viewonline = (!empty($_POST['viewonline'])) ? 0 : 1;
    	$admin = 0;
  • Le tout est envoyé à une fonction de phpBB qui se charge de vérifier la validité des pseudo et mot de passe et connecte l'utilisateur en cas de succès
    Code: Tout sélectionner
    	$result = $auth->login($username, $password, $autologin, $viewonline, $admin);

    cette fonction place en retour dans la variable $result un tableau avec 2 clés:
    • status: qui prend la valeur de la constante LOGIN_SUCCESS en cas de succès
    • error_msg vide en cas de succès, sinon contient la clé de langue du message d'erreur
  • donc, en cas d'échec, on récupère le message d'erreur, avec un lien vers le mail de l'admin si c'est un pseudo ou mot de passe erroné
    Code: Tout sélectionner
    	if ($result['status'] != LOGIN_SUCCESS)
    	{
    		$err = $user->lang[$result['error_msg']];
    		if ($result['error_msg'] == 'LOGIN_ERROR_USERNAME' || $result['error_msg'] == 'LOGIN_ERROR_PASSWORD')
    		{
    			$err = (!$config['board_contact']) ? sprintf($user->lang[$result['error_msg']], '', '') : sprintf($user->lang[$result['error_msg']], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>');
    		}
    	}
  • sinon, l'utilisateur s'est connecté avec succès et on récupère ses permissions
    Code: Tout sélectionner
    	else
    	{
    		$auth->acl($user->data);
    	}
    

    et on n'oublie pas l'accolade de fermeture du test if (isset($_POST['login']))
    Code: Tout sélectionner
    }
Arrivés à ce stade, toutes les données de connexion ont été recueillies, et vous pouvez maintenant, et seulement maintenant afficher du texte, par exemple en incluant le fichier qui va afficher l'entête de votre site (si vous aviez affiché du texte avant, vous auriez droit à une erreur 'header already sent' parce que la fonction $auth->login redémarre une session en cas de succès de connexion et, les sessions utilisant les cookies, aucun texte ne doit être affiché avant un démarrage de session
maintenant de deux choses l'une, l'utilisateur est connecté ou il ne l'est pas
  • il est connecté
    on va afficher son pseudo et un lien vers la déconnexion
    Code: Tout sélectionner
    if ($user->data['user_id'] != ANONYMOUS)
    {
    	echo 'Bienvenue ' . $user->data['username'] . '<br />';
    	echo '<a href="' . append_sid('mon_login.php?logout=true') . '">Déconnexion</a>';
    }
    
  • il n'est pas connecté
    • en cas d'erreur, on affiche d'abord le message d'erreur
      Code: Tout sélectionner
      else
      {
      	if($err)
      	{
      		echo "<font color=red><b>$err</b></font>";
      	}
      
    • et ensuite le formulaire
      Code: Tout sélectionner
      ?>
      <form method="post">
      	<table>
      		<tr>
      			<td align="right">Pseudo:</td>
      			<td><input type="text" tabindex="1" name="username" size="25" /></td>
      		</tr>
      		<tr>
      			<td align="right">Mot de passe:</td>
      			<td><input type="password" tabindex="2" name="password" size="25" /></td>
      		</tr>
      		<tr>
      			<td>&nbsp;</td>
      			<td><input type="checkbox" name="autologin" tabindex="3" /> Me connecter automatiquement à chaque visite</td>
      		</tr>
      		<tr>
      			<td>&nbsp;</td>
      			<td><input type="checkbox" name="viewonline" tabindex="4" /> Cacher mon statut en ligne pour cette session</td>
      		</tr>
      		<tr>
      			<td colspan="2" align="center"><input type="submit" name="login" tabindex="5" value="Connexion" /></td>
      		</tr>
      	</table>
      </form>
      <?php
      }
      ?>
    • vous pouvez éventuellement ajouter, en dessous du champ mot de passe, un lien vers la demande de nouveau mot de passe (mais dans ce cas, ça passera par le forum)
      Code: Tout sélectionner
      <a href="<?php echo append_sid("{$phpbb_root_path}ucp.$phpEx?mode=sendpassword"); ?>">J’ai oublié mon mot de passe</a>
et voilà le script complet
Code: Tout sélectionner
<?php
define('IN_PHPBB', true);
$phpbb_root_path =  './phpbb3/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
$user->session_begin();
$auth->acl($user->data);
$user->setup('');
if (isset($_GET['logout']))
{
	$user->session_kill();
	$user->session_begin();
}
if (isset($_POST['login']))
{
	$username = request_var('username', '', true);
	$password    = request_var('password', '', true);
	$autologin   = (!empty($_POST['autologin'])) ? true : false;
	$viewonline = (!empty($_POST['viewonline'])) ? 0 : 1;
	$admin = 0;
	$result = $auth->login($username, $password, $autologin, $viewonline, $admin);
	if ($result['status'] != LOGIN_SUCCESS)
	{
		$err = $user->lang[$result['error_msg']];
		if ($result['error_msg'] == 'LOGIN_ERROR_USERNAME' || $result['error_msg'] == 'LOGIN_ERROR_PASSWORD')
		{
			$err = (!$config['board_contact']) ? sprintf($user->lang[$result['error_msg']], '', '') : sprintf($user->lang[$result['error_msg']], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>');
		}
	}
	else
	{
		$auth->acl($user->data);
	}
}
if ($user->data['user_id'] != ANONYMOUS)
{
	echo 'Bienvenue ' . $user->data['username'] . '<br />';
	echo '<a href="' . append_sid('mon_login.php?logout=true') . '">Déconnexion</a>';
}
else
{
if($err)
	{
		echo "<font color=red><b>$err</b></font>";
	}
?>
<form method="post">
	<table>
		<tr>
			<td align="right">Pseudo:</td>
			<td><input type="text" tabindex="1" name="username" size="25" /></td>
		</tr>
		<tr>
			<td align="right">Mot de passe:</td>
			<td><input type="password" tabindex="2" name="password" size="25" />
			<br /><a href="<?php echo append_sid("{$phpbb_root_path}ucp.$phpEx?mode=sendpassword"); ?>">J’ai oublié mon mot de passe</a>
			</td>
		</tr>
		<tr>
		
		</tr>
		<tr>
			<td>&nbsp;</td>
			<td><input type="checkbox" name="autologin" tabindex="3" /> Me connecter automatiquement à chaque visite</td>
		</tr>
		<tr>
			<td>&nbsp;</td>
			<td><input type="checkbox" name="viewonline" tabindex="4" /> Cacher mon statut en ligne pour cette session</td>
		</tr>
		<tr>
			<td colspan="2" align="center"><input type="submit" name="login" tabindex="5" value="Connexion" /></td>
		</tr>
	</table>
</form>
<?php
}
?>



2-b Créer un formulaire de connexion - version templatée

Si on utilise les sessions phpBB, il est plus intéressant d'utiliser les templates, ce qui permet une mise en page plus cohérente.
Pour aprofondir vos connaissances sur les templates, voir ce tutoriel

  • Côté html
    nous allons bâtir un fichier nommé mon_login_body.html.
    • il comportera un bloc conditionnel selon le statut de connexion
      Code: Tout sélectionner
      <!-- IF S_REGISTERED -->
      donc ce qui suit ne s'affichera que si l'utilisateur est connecté.
    • on va mettre un message de bienvenue à l'utilisateur et un lien de déconnexion
      Code: Tout sélectionner
      	{L_WELCOME} {USERNAME}<br />
      	<a href="{U_LOGOUT}">{L_LOGOUT}</a>
      la variable L_WELCOME fait référence à une clé de langue 'WELCOME' qui n'existe pas, il va donc falloir la créer
      éditez langauage/fr/common.php, cherchez
      Code: Tout sélectionner
      	'WARN_USER'			=> 'Avertir l’utilisateur',
      et ajoutez après
      Code: Tout sélectionner
      	'WELCOME'			=> 'Bienvenue ',

    • on termine ce bloc par
      Code: Tout sélectionner
      <!-- ELSE -->
      ce qui suit ne s'affichera donc que si l'utilisateur n'est pas connecté
    • on teste d'abord s'il y a une erreur et si oui on l'affiche
      Code: Tout sélectionner
      	<!-- IF S_ERROR -->
      	<font color="red"><b>{S_ERROR}</b></font>
      	<!-- ENDIF -->

    • le reste est le formulaire, identique à celui du chapitre précédent, sauf que tous les labels de champs ont été remplacés par des clés de langue
      Code: Tout sélectionner
      	<table>
      		<tr>
      			<td align="right">{L_USERNAME}:</td>
      			<td><input type="text" tabindex="1" name="username" size="25" /></td>
      		</tr>
      		<tr>
      			<td align="right">{L_PASSWORD}:</td>
      			<td><input type="password" tabindex="2" name="password" size="25" />
      			<br /><a href="{U_SEND_PASSWORD}">{L_FORGOT_PASS}</a>
      			</td>
      		</tr>
      		<tr>
      		</tr>
      		<tr>
      			<td>&nbsp;</td>
      			<td><input type="checkbox" name="autologin" tabindex="3" />{L_LOG_ME_IN}</td>
      		</tr>
      		<tr>
      			<td>&nbsp;</td>
      			<td><input type="checkbox" name="viewonline" tabindex="4" />{L_HIDE_ME}</td>
      		</tr>
      		<tr>
      			<td colspan="2" align="center"><input type="submit" name="login" tabindex="5" value="{L_LOGIN}" /></td>
      		</tr>
      	</table>
      	</form>

    • et on n'ouble pas le ENDIF qui termine le bloc conditionnel
      Code: Tout sélectionner
      <!-- ENDIF -->
    et voilà le fichier complet. vous remarquerez l'encodage UTF-8 dans l'entête, nécessaire parce que c'est l'encodage des fichiers de langue
    Code: Tout sélectionner
    <html>
    <head>
    	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    	<title>{TITLE}</title>
    </head>
    <body>
    <!-- IF S_REGISTERED -->
    	{L_WELCOME} {USERNAME}<br />
    	<a href="{U_LOGOUT}">{L_LOGOUT}</a>
    <!-- ELSE -->
    	<!-- IF S_ERROR -->
    	<font color="red"><b>{S_ERROR}</b></font>
    	<!-- ENDIF -->
    	<form method="post">
    	<table>
    		<tr>
    			<td align="right">{L_USERNAME}:</td>
    			<td><input type="text" tabindex="1" name="username" size="25" /></td>
    		</tr>
    		<tr>
    			<td align="right">{L_PASSWORD}:</td>
    			<td><input type="password" tabindex="2" name="password" size="25" />
    			<br /><a href="{U_SEND_PASSWORD}">{L_FORGOT_PASS}</a>
    			</td>
    		</tr>
    		<tr>
    		</tr>
    		<tr>
    			<td>&nbsp;</td>
    			<td><input type="checkbox" name="autologin" tabindex="3" />{L_LOG_ME_IN}</td>
    		</tr>
    		<tr>
    			<td>&nbsp;</td>
    			<td><input type="checkbox" name="viewonline" tabindex="4" />{L_HIDE_ME}</td>
    		</tr>
    		<tr>
    			<td colspan="2" align="center"><input type="submit" name="login" tabindex="5" value="{L_LOGIN}" /></td>
    		</tr>
    	</table>
    	</form>
    <!-- ENDIF -->
    </body>
    </html>
  • Côté php
    • la vérication des conditions de connexion est strictement identique au code du chapitre précédent
    • ensuite on associe le script au fichier mon_login_body.html
      Code: Tout sélectionner
      $template->set_filenames(array('body' => 'mon_login_body.html'));

    • on assigne les variables du template
      Code: Tout sélectionner
      $template->assign_vars(array(
      	'TITLE' => ($user->data['user_id'] != ANONYMOUS) ? $user->lang['WELCOME'] : $user->lang['LOGIN'],
      	'S_REGISTERED' => ($user->data['user_id'] != ANONYMOUS) ? true : false,
      	'S_ERROR' => $err,
      	'USERNAME' => $user->data['username'],
      	'U_LOGOUT' => append_sid('mon_login.php?logout=true'),
      	'U_SEND_PASSWORD' => append_sid("{$phpbb_root_path}ucp.$phpEx?mode=sendpassword")
      ));

    • et on termine par l'affichage du template
      Code: Tout sélectionner
      $template->display('body');
    et voilà le fichier complet
    Code: Tout sélectionner
    <?php
    define('IN_PHPBB', true);
    $phpbb_root_path =  './phpbb3/';
    $phpEx = substr(strrchr(__FILE__, '.'), 1);
    include($phpbb_root_path . 'common.' . $phpEx);
    $user->session_begin();
    $auth->acl($user->data);
    $user->setup('');
    if (isset($_GET['logout']))
    {
    	$user->session_kill();
    	$user->session_begin();
    }
    if (isset($_POST['login']))
    {
    	$username = request_var('username', '', true);
    	$password    = request_var('password', '', true);
    	$autologin   = (!empty($_POST['autologin'])) ? true : false;
    	$viewonline = (!empty($_POST['viewonline'])) ? 0 : 1;
    	$admin = 0;
    	$result = $auth->login($username, $password, $autologin, $viewonline, $admin);
    	if ($result['status'] != LOGIN_SUCCESS)
    	{
    		$err = $user->lang[$result['error_msg']];
    		if ($result['error_msg'] == 'LOGIN_ERROR_USERNAME' || $result['error_msg'] == 'LOGIN_ERROR_PASSWORD')
    		{
    			$err = (!$config['board_contact']) ? sprintf($user->lang[$result['error_msg']], '', '') : sprintf($user->lang[$result['error_msg']], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>');
    		}
    	}
    	else
    	{
    		$auth->acl($user->data);
    	}
    }
    $template->set_filenames(array('body' => 'mon_login_body.html'));
    $template->assign_vars(array(
    	'TITLE' => ($user->data['user_id'] != ANONYMOUS) ? $user->lang['WELCOME'] : $user->lang['LOGIN'],
    	'S_REGISTERED' => ($user->data['user_id'] != ANONYMOUS) ? true : false,
    	'S_ERROR' => $err,
    	'USERNAME' => $user->data['username'],
    	'U_LOGOUT' => append_sid('mon_login.php?logout=true'),
    	'U_SEND_PASSWORD' => append_sid("{$phpbb_root_path}ucp.$phpEx?mode=sendpassword")
    ));
    $template->display('body');
    ?>


3-a Enregistrer de nouveaux utilisateurs à partir de votre site

Vous avez accès aux sessions phpBB, vos utilisateurs peuvent se connecter directement sur votre site.
Maintenant, vous aimeriez bien que de nouveaux utilisateurs puissent s'inscrire sans avoir à passer par le forum.
Pour celà, nous allons utiliser la fonction user_add() qui se trouve dans le fichier includes/functions_user.php
Nous allons utiliser un formulaire ultra simplifié: juste pseudo, mot de passe, email et confirmation email et mot de passe.
le fuseau horaire et la langue seront ceux définis par défaut dans le panneau d'admin.
un captcha peut être ajouté qui ne s'affichera que si vous l'avez paramétré dans le panneau d'administration.
  • Le démarrage de la session est comme d'habitude, à ceci près:
    - qu'il faudra inclure le fichier includes/function_user.php pour pouvoir utiliser les fonctions validate_data et user_add
    - nous aurons besoin des clés de langue de language/fr/ucp.php, donc l'appel de $user->setup deviendra:
    Code: Tout sélectionner
    $user->setup('ucp');
  • si vous voulez afficher un captcha, ajoutez ces lignes
    Code: Tout sélectionner
    if ($config['enable_confirm'])
    {
    	include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
    	$captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
    	$captcha->init(CONFIRM_REG);
    }
  • nous récupérons dans un tableau $data les variables de retour du formulaire (en encodant le pseudo en utf8)
    Code: Tout sélectionner
    $data = array(
    	'username'			=> utf8_normalize_nfc(request_var('username', '', true)),
    	'password'			=> request_var('password', '', true),
    	'password_confirm'	=> request_var('password_confirm', '', true),
    	'email'				=> strtolower(request_var('email', '')),
    	'email_confirm'		=> strtolower(request_var('email_confirm', '')),
    );
    Nous faisons ça avant de tester si le formulaire a été validé, car nous aurons besoin de ces variables, même vides, pour remplir la valeur des champs du formulaire. Ca évitera des erreurs du type 'notice: key username undefined'
  • maintenant on teste si le formulaire a été validé
    Code: Tout sélectionner
    if (isset($_POST['submit']))
    {
  • Le formulaire a été validé, on va tester la validité de la réponse avec la fonction validate_data qui vérifie l'absence de caractères interdits, le format correct de l'email, la taille minimum des différents champs et vérifie aussi si le pseudo n'est pas déjà utilisé:
    Code: Tout sélectionner
    	$error = validate_data($data, array(
    		'username'			=> array(
    			array('string', false, $config['min_name_chars'], $config['max_name_chars']),
    			array('username', '')),
    		'password'		=> array(
    			array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
    			array('password')),
    		'password_confirm'	=> array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
    		'email'				=> array(
    			array('string', false, 6, 60),
    			array('email')),
    		'email_confirm'		=> array('string', false, 6, 60),
    	));
  • le tableau $error, qui contient, si erreur, une liste de clés de langue est traduit dans la langue courante
    Code: Tout sélectionner
    $error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
  • si vous voulez utiliser un captcha, ajoutez ces lignes
    Code: Tout sélectionner
    	if ($config['enable_confirm'])
    	{
    		$vc_response = $captcha->validate($data);
    		if ($vc_response !== false)
    		{
    			$error[] = $vc_response;
    		}
    
    		if ($config['max_reg_attempts'] && $captcha->get_attempt_count() > $config['max_reg_attempts'])
    		{
    			$error[] = $user->lang['TOO_MANY_REGISTERS'];
    		}
    	}
  • Il n'y a pas d'erreurs, on regarde si le mot de passe correspond bien à la confirmation du mot de passe, idem pour l'email
    Code: Tout sélectionner
    	if (!sizeof($error))
    	{
    		if ($data['password'] != $data['password_confirm'])
    		{
    			$error[] = $user->lang['NEW_PASSWORD_ERROR'];
    		}
    		if ($data['email'] != $data['email_confirm'])
    		{
    			$error[] = $user->lang['NEW_EMAIL_ERROR'];
    		}
    	}
  • Il n'y a pas d'erreur, la fiche va être maintenant enregistrée:
    • On récupère le n° de groupe auquel l'utilisateur va être inscrit par défaut (ici, ça sera le groupe 'REGISTERED', vous pouvez changer de nom de groupe si vous le souhaitez)
      Code: Tout sélectionner
      	if (!sizeof($error))
      	{
      		$group_name =  'REGISTERED';
      		$sql = 'SELECT group_id
      					FROM ' . GROUPS_TABLE . "
      					WHERE group_name = '" . $db->sql_escape($group_name) . "'
      						AND group_type = " . GROUP_SPECIAL;
      		$result = $db->sql_query($sql);
      		$row = $db->sql_fetchrow($result);
      		$db->sql_freeresult($result);
      		if (!$row)
      		{
      			trigger_error('NO_GROUP');
      		}
      		$group_id = $row['group_id'];
    • maintenant on remplit le tableau $user_row avec les données du formulaire + les valeurs par défaut de la langue et du fuseau horaire, on choisit un type d'utilisateur normal et actif (pas d'attente de validation par admin ou par email)
      Code: Tout sélectionner
      		$user_row = array(
      			'username'				=> $data['username'],
      			'user_password'			=> phpbb_hash($data['password']),
      			'user_email'			=> $data['email'],
      			'group_id'				=> (int) $group_id,
      			'user_timezone'			=> (float) $config['board_timezone'],
      			'user_dst'				=> $config['board_dst'],
      			'user_lang'				=> basename($user->lang_name),
      			'user_type'				=> USER_NORMAL,
      			'user_actkey'			=> '',
      			'user_ip'				=> $user->ip,
      			'user_regdate'			=> time(),
      			'user_inactive_reason'	=> 0,
      			'user_inactive_time'	=> 0,
      		);
    • et on envoie ce tableau à la fonction user_add()
      Code: Tout sélectionner
      		$user_id = user_add($user_row);
    • la fonction envoie en retour l'id de l'utilisateur. si cette id est vide, on déclenche une erreur
      Code: Tout sélectionner
      		if ($user_id === false)
      		{
      			trigger_error('NO_USER', E_USER_ERROR);
      		}
    • si vous voulez utiliser un captcha, ajoutez ces lignes
      Code: Tout sélectionner
      		if ($config['enable_confirm'])
      		{
      			$captcha->reset();
      		}
    • Tout s'est bien passé, l'utilisateur va être maintenant redirigé, ici vers l'index.php de votre site
      Code: Tout sélectionner
      		$url = append_sid('./index.php');
      		die( '<html>
      			<head>
      				<META http-equiv="Refresh"
      				content="10; URL=' . $url . '">
      			</head>
      			<body>
      			Votre compte a été enregistré avec succès<br />
      			Vous allez être maintenant redirigé vers <a href="' . $url . '">la page d\'index</a>
      			</body>
      		</html>');
    • et on n'oublie pas les accolades de fermeture des 2 tests:
      Code: Tout sélectionner
      	}
      }
  • Au point où nous arrivons soit l'utilisateur vient d'entrer dans le formulaire, soit sa réponse au formulaire a échoué.
    • d'abord l'entête du formulaire avec un encodage utf8
      Code: Tout sélectionner
      echo '<html>
      <head>
      	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
      	<title>Vous enregistrer</title>
      </head>
      <body>
      	<form method="post">
      <h1>Vous enregistrer</h1>';
    • en cas d'echec du formulaire, on affiche les erreurs
      Code: Tout sélectionner
      if (sizeof($error))
      {
      	echo '<font color="red"><b>' . implode('<br />', $error) . '</b></font>';;
      
      }
    • Le reste est un formulaire, sans particularités
      Code: Tout sélectionner
      ?>
      <table>
      	<tr>
      		<td align="right">Pseudonyme:</td>
      		<td><input type="text" tabindex="1" name="username" size="25" value="<?php echo $data['username']; ?>" /></td>
      	</tr>
      	<tr>
      		<td align="right">Mot de passe:</td>
      		<td><input type="password" tabindex="2" name="password" size="25" value="<?php echo $data['password']; ?>" /></td>
      	</tr>
      	<tr>
      		<td align="right">Confirmez votre mot de passe:</td>
      		<td><input type="password" tabindex="3" name="password_confirm" size="25" value="<?php echo $data['password_confirm']; ?>" /></td>
      	</tr>
      	<tr>
      		<td align="right">Email:</td>
      		<td><input type="text" tabindex="4" name="email" size="25" maxlength="100" value="<?php echo $data['email']; ?>" /></td>
      	</tr>
      	<tr>
      		<td align="right">Confirmez votre Email</td>
      		<td><input type="text" tabindex="5" name="email_confirm" size="25" maxlength="100" value="<?php echo $data['email_confirm']; ?>" /></td>
      	</tr>
      
    • si vous voulez utiliser un captcha, ajoutez ces lignes
      Code: Tout sélectionner
      <?php
      if ($config['enable_confirm'])
      {
      	$confirm_id = $captcha->confirm_id;
      	$confirm_code = true;
      	$confirm_image='<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=confirm&amp;confirm_id=' . $confirm_id . '&amp;type=' . CONFIRM_REG) . '" alt="" title="" />';
      ?>
         <tr>
            <td><?php echo $user->lang['CONFIRM_CODE'] . '<br />' . $user->lang['CONFIRM_CODE_EXPLAIN']; ?></td>
            <td><input type="hidden" name="confirm_id" value="<?php echo $confirm_id; ?>" /><?php echo $confirm_image; ?></td>
         </tr>
         <tr>
            <td>&nbsp;</td>
            <td><input type="text" name="confirm_code" id="confirm_code" size="8" maxlength="8" /></td>
         </tr>
      <?php
      }
      ?>
      }
      
    • et on termine par le bouton de validation
      Code: Tout sélectionner
      	<tr>
      		<td colspan="2" align="center">
      			<input type="reset" value="Remettre &agrave; z&eacute;ro" name="reset" />&nbsp;
      			<input type="submit" name="submit" id ="submit" value="S'enregistrer" />
      		</td>
      	</tr>
      </table>
      </form>
      </body>
      </html>
et voilà le script complet sans captcha
Code: Tout sélectionner
<?php
define('IN_PHPBB', true);
$phpbb_root_path =  './phpBB3/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
require($phpbb_root_path . 'includes/functions_user.' . $phpEx);
$user->session_begin();
$auth->acl($user->data);
$user->setup('ucp');
$error=array();
$data = array(
	'username'			=> utf8_normalize_nfc(request_var('username', '', true)),
	'password'			=> request_var('password', '', true),
	'password_confirm'	=> request_var('password_confirm', '', true),
	'email'				=> strtolower(request_var('email', '')),
	'email_confirm'		=> strtolower(request_var('email_confirm', '')),
);
if (isset($_POST['submit']))
{
	$error = validate_data($data, array(
		'username'			=> array(
			array('string', false, $config['min_name_chars'], $config['max_name_chars']),
			array('username', '')),
		'password'		=> array(
			array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
			array('password')),
		'password_confirm'	=> array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
		'email'				=> array(
			array('string', false, 6, 60),
			array('email')),
		'email_confirm'		=> array('string', false, 6, 60),
	));
	$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
	if (!sizeof($error))
	{
		if ($data['password'] != $data['password_confirm'])
		{
			$error[] = $user->lang['NEW_PASSWORD_ERROR'];
		}
		if ($data['email'] != $data['email_confirm'])
		{
			$error[] = $user->lang['NEW_EMAIL_ERROR'];
		}
	}
	if (!sizeof($error))
	{
		$group_name =  'REGISTERED';
		$sql = 'SELECT group_id
					FROM ' . GROUPS_TABLE . "
					WHERE group_name = '" . $db->sql_escape($group_name) . "'
						AND group_type = " . GROUP_SPECIAL;
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);
		if (!$row)
		{
			trigger_error('NO_GROUP');
		}
		$group_id = $row['group_id'];
		$user_row = array(
			'username'				=> $data['username'],
			'user_password'			=> phpbb_hash($data['password']),
			'user_email'			=> $data['email'],
			'group_id'				=> (int) $group_id,
			'user_timezone'			=> (float) $config['board_timezone'],
			'user_dst'				=> $config['board_dst'],
			'user_lang'				=> basename($user->lang_name),
			'user_type'				=> USER_NORMAL,
			'user_actkey'			=> '',
			'user_ip'				=> $user->ip,
			'user_regdate'			=> time(),
			'user_inactive_reason'	=> 0,
			'user_inactive_time'	=> 0,
		);
		$user_id = user_add($user_row);
		if ($user_id === false)
		{
			trigger_error('NO_USER', E_USER_ERROR);
		}
		$url = append_sid('./index.php');
		die( '<html>
			<head>
				<META http-equiv="Refresh"
				content="10; URL=' . $url . '">
			</head>
			<body>
			Votre compte a été enregistré avec succès<br />
			Vous allez être maintenant redirigé vers <a href="' . $url . '">la page d\'index</a>
			</body>
		</html>');
	}
}
echo '<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<title>Vous enregistrer</title>
</head>
<body>
	<form method="post">
<h1>Vous enregistrer</h1>';
if (sizeof($error))
{
	echo '<font color="red"><b>' . implode('<br />', $error) . '</b></font>';;

}
?>
<table>
	<tr>
		<td align="right">Pseudonyme:</td>
		<td><input type="text" tabindex="1" name="username" size="25" value="<?php echo $data['username']; ?>" /></td>
	</tr>
	<tr>
		<td align="right">Mot de passe:</td>
		<td><input type="password" tabindex="2" name="password" size="25" value="<?php echo $data['password']; ?>" /></td>
	</tr>
	<tr>
		<td align="right">Confirmez votre mot de passe:</td>
		<td><input type="password" tabindex="3" name="password_confirm" size="25" value="<?php echo $data['password_confirm']; ?>" /></td>
	</tr>
	<tr>
		<td align="right">Email:</td>
		<td><input type="text" tabindex="4" name="email" size="25" maxlength="100" value="<?php echo $data['email']; ?>" /></td>
	</tr>
	<tr>
		<td align="right">Confirmez votre Email</td>
		<td><input type="text" tabindex="5" name="email_confirm" size="25" maxlength="100" value="<?php echo $data['email_confirm']; ?>" /></td>
	</tr>
	<tr>
		<td colspan="2" align="center">
			<input type="reset" value="Remettre &agrave; z&eacute;ro" name="reset" />&nbsp;
			<input type="submit" name="submit" id ="submit" value="S'enregistrer" />
		</td>
	</tr>
</table>
</form>
</body>
</html>

et avec captcha
Code: Tout sélectionner
<?php
define('IN_PHPBB', true);
$phpbb_root_path =  './phpBB3/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
require($phpbb_root_path . 'includes/functions_user.' . $phpEx);
$user->session_begin();
$auth->acl($user->data);
$user->setup('ucp');
//ajout captcha
if ($config['enable_confirm'])
{
	include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
	$captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
	$captcha->init(CONFIRM_REG);
}
//
$error=array();
$data = array(
   'username'         => utf8_normalize_nfc(request_var('username', '', true)),
   'password'         => request_var('password', '', true),
   'password_confirm'   => request_var('password_confirm', '', true),
   'email'            => strtolower(request_var('email', '')),
   'email_confirm'      => strtolower(request_var('email_confirm', '')),
);
if (isset($_POST['submit']))
{
	$error = validate_data($data, array(
	   'username'         => array(
	      array('string', false, $config['min_name_chars'], $config['max_name_chars']),
	      array('username', '')),
	   'password'      => array(
	      array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
	      array('password')),
	   'password_confirm'   => array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
	   'email'            => array(
	      array('string', false, 6, 60),
	      array('email')),
	   'email_confirm'      => array('string', false, 6, 60),
	));
	$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
	
	//ajout captcha
	if ($config['enable_confirm'])
	{
		$vc_response = $captcha->validate($data);
		if ($vc_response !== false)
		{
			$error[] = $vc_response;
		}

		if ($config['max_reg_attempts'] && $captcha->get_attempt_count() > $config['max_reg_attempts'])
		{
			$error[] = $user->lang['TOO_MANY_REGISTERS'];
		}
	}
	//
	if (!sizeof($error))
	{
		if ($data['password'] != $data['password_confirm'])
		{
			$error[] = $user->lang['NEW_PASSWORD_ERROR'];
		}
		if ($data['email'] != $data['email_confirm'])
		{
			$error[] = $user->lang['NEW_EMAIL_ERROR'];
		}
	}
	if (!sizeof($error))
	{
		$group_name =  'REGISTERED';
		$sql = 'SELECT group_id
			FROM ' . GROUPS_TABLE . "
			WHERE group_name = '" . $db->sql_escape($group_name) . "'
				AND group_type = " . GROUP_SPECIAL;
		$result = $db->sql_query($sql);
		$row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);
		if (!$row)
		{
			trigger_error('NO_GROUP');
		}
		$group_id = $row['group_id'];
		$user_row = array(
		   'username'            => $data['username'],
		   'user_password'         => phpbb_hash($data['password']),
		   'user_email'         => $data['email'],
		   'group_id'            => (int) $group_id,
		   'user_timezone'         => (float) $config['board_timezone'],
		   'user_dst'            => $config['board_dst'],
		   'user_lang'            => basename($user->lang_name),
		   'user_type'            => USER_NORMAL,
		   'user_actkey'         => '',
		   'user_ip'            => $user->ip,
		   'user_regdate'         => time(),
		   'user_inactive_reason'   => 0,
		   'user_inactive_time'   => 0,
		);
		$user_id = user_add($user_row);
		if ($user_id === false)
		{
			trigger_error('NO_USER', E_USER_ERROR);
		}
		//ajout captcha
		if ($config['enable_confirm'])
		{
			$captcha->reset();
		}
		$url = append_sid('./index.php');
		die( '<html>
		   <head>
		      <META http-equiv="Refresh"
		      content="10; URL=' . $url . '">
		   </head>
		   <body>
		   Votre compte a été enregistré avec succès<br />
		   Vous allez être maintenant redirigé vers <a href="' . $url . '">la page d\'index</a>
		   </body>
		</html>');
	}
}
echo '<html>
<head>
   <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
   <title>Vous enregistrer</title>
</head>
<body>
   <form method="post">
<h1>Vous enregistrer</h1>';
//ajout patcha
if ($config['enable_confirm'])
{
	$confirm_id = $captcha->confirm_id;
	$confirm_code = true;
	$confirm_image='<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=confirm&amp;confirm_id=' . $confirm_id . '&amp;type=' . CONFIRM_REG) . '" alt="" title="" />';
}
if (sizeof($error))
{
	echo '<font color="red"><b>' . implode('<br />', $error) . '</b></font>';;

}
?>
<table>
   <tr>
      <td align="right">Pseudonyme:</td>
      <td><input type="text" tabindex="1" name="username" size="25" value="<?php echo $data['username']; ?>" /></td>
   </tr>
   <tr>
      <td align="right">Mot de passe:</td>
      <td><input type="password" tabindex="2" name="password" size="25" value="<?php echo $data['password']; ?>" /></td>
   </tr>
   <tr>
      <td align="right">Confirmez votre mot de passe:</td>
      <td><input type="password" tabindex="3" name="password_confirm" size="25" value="<?php echo $data['password_confirm']; ?>" /></td>
   </tr>
   <tr>
      <td align="right">Email:</td>
      <td><input type="text" tabindex="4" name="email" size="25" maxlength="100" value="<?php echo $data['email']; ?>" /></td>
   </tr>
   <tr>
      <td align="right">Confirmez votre Email</td>
      <td><input type="text" tabindex="5" name="email_confirm" size="25" maxlength="100" value="<?php echo $data['email_confirm']; ?>" /></td>
   </tr>
<?php
if ($confirm_code)
{
?>
   <tr>
      <td><?php echo $user->lang['CONFIRM_CODE'] . '<br />' . $user->lang['CONFIRM_CODE_EXPLAIN']; ?></td>
      <td><input type="hidden" name="confirm_id" value="<?php echo $confirm_id; ?>" /><?php echo $confirm_image; ?></td>
   </tr>
   <tr>
      <td>&nbsp;</td>
      <td><input type="text" name="confirm_code" id="confirm_code" size="8" maxlength="8" /></td>
   </tr>
<?php
}
?>
   <tr>
      <td colspan="2" align="center">
         <input type="reset" value="Remettre &agrave; z&eacute;ro" name="reset" />&nbsp;
         <input type="submit" name="submit" id ="submit" value="S'enregistrer" />
      </td>
   </tr>
</table>
</form>
</body>
</html>



3-b Enregistrer de nouveaux utilisateurs à partir de votre site - version templatée
je ne vais pas trop rentrer dans les détails
  • côté html
    on crée un fichier nommé register_body.html, à placer dans styles/prosilver/template/
    la variable S_SUCCESS, si vraie, place dans l'entête la meta de redirection et dans le corps de la page le message de succès
    sinon le formulaire est affiché avec les variables label (commençant par L_) assignées automatiquement par le moteur de template et les variables valeur de champ qui seront assignées par le script php.
    de plus si la variable MESSAGE_ERROR n'est pas vide, on affiche avant le formulaire, les messages d'erreur
    Code: Tout sélectionner
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <!-- IF S_SUCCESS -->
    <META http-equiv="Refresh" 	content="10; URL={U_REDIRECT}">
    <!-- ELSE -->
    <title>{L_REGISTER}</title>
    <!-- ENDIF -->
    </head>
    <body>
    <!-- IF S_SUCCESS -->
    {MESSAGE}
    <!-- ELSE -->
    	<h1>{L_REGISTER}</h1>
    	<!-- IF MESSAGE_ERROR -->
    	<font color="red"><b>{MESSAGE_ERROR}</b></font>
    	<!-- ENDIF -->
    	<form method="post">
    		<table>
    			<tr>
    				<td align="right">{L_USERNAME}:</td>
    				<td><input type="text" tabindex="1" name="username" size="25" value="{USERNAME}" /></td>
    			</tr>
    			<tr>
    				<td align="right">{L_PASSWORD}:</td>
    				<td><input type="password" tabindex="2" name="password" size="25" value="{PASSWORD}" /></td>
    			</tr>
    			<tr>
    				<td align="right">{L_CONFIRM_PASSWORD}:</td>
    				<td><input type="password" tabindex="3" name="password_confirm" size="25" value="{PASSWORD_CONFIRM}" /></td>
    			</tr>
    			<tr>
    				<td align="right">{L_EMAIL_ADDRESS}:</td>
    				<td><input type="text" tabindex="4" name="email" size="25" maxlength="100" value="{EMAIL}" /></td>
    			</tr>
    			<tr>
    				<td align="right">{L_CONFIRM_EMAIL}:</td>
    				<td><input type="text" tabindex="5" name="email_confirm" size="25" maxlength="100" value="{EMAIL_CONFIRM}" /></td>
    			</tr>
    			<tr>
    				<td colspan="2" align="center">
    					<input type="reset" value="{L_RESET}" name="reset" />&nbsp;
    					<input type="submit" name="submit" id ="submit" value="{L_SUBMIT}" />
    				</td>
    			</tr>
    		</table>
    	</form>
    <!-- ENDIF -->
    </body>
    </html>
  • Côté php
    pas de différences avec le précédent chapitre, en ce qui concerne le recueil, le test et l'enregistrement des données.
    et après on assigne les variables template
    Code: Tout sélectionner
    <?php
    define('IN_PHPBB', true);
    $phpbb_root_path =  './phpBB3/';
    $phpEx = substr(strrchr(__FILE__, '.'), 1);
    include($phpbb_root_path . 'common.' . $phpEx);
    require($phpbb_root_path . 'includes/functions_user.' . $phpEx);
    $user->session_begin();
    $auth->acl($user->data);
    $user->setup('ucp');
    $error=array();
    $success = false;
    $message_error = '';
    $url_redirect='';
    $data = array(
    	'username'			=> utf8_normalize_nfc(request_var('username', '', true)),
    	'password'			=> request_var('password', '', true),
    	'password_confirm'	=> request_var('password_confirm', '', true),
    	'email'				=> strtolower(request_var('email', '')),
    	'email_confirm'		=> strtolower(request_var('email_confirm', '')),
    );
    if (isset($_POST['submit']))
    {
    	$error = validate_data($data, array(
    		'username'			=> array(
    			array('string', false, $config['min_name_chars'], $config['max_name_chars']),
    			array('username', '')),
    		'password'		=> array(
    			array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
    			array('password')),
    		'password_confirm'	=> array('string', false, $config['min_pass_chars'], $config['max_pass_chars']),
    		'email'				=> array(
    			array('string', false, 6, 60),
    			array('email')),
    		'email_confirm'		=> array('string', false, 6, 60),
    	));
    	$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
    	if (!sizeof($error))
    	{
    		if ($data['password'] != $data['password_confirm'])
    		{
    			$error[] = $user->lang['NEW_PASSWORD_ERROR'];
    		}
    		if ($data['email'] != $data['email_confirm'])
    		{
    			$error[] = $user->lang['NEW_EMAIL_ERROR'];
    		}
    	}
    	if (!sizeof($error))
    	{
    		$group_name =  'REGISTERED';
    		$sql = 'SELECT group_id
    				FROM ' . GROUPS_TABLE . "
    				WHERE group_name = '" . $db->sql_escape($group_name) . "'
    					AND group_type = " . GROUP_SPECIAL;
    		$result = $db->sql_query($sql);
    		$row = $db->sql_fetchrow($result);
    		$db->sql_freeresult($result);
    		if (!$row)
    		{
    			trigger_error('NO_GROUP');
    		}
    		$group_id = $row['group_id'];
    		$user_row = array(
    			'username'				=> $data['username'],
    			'user_password'			=> phpbb_hash($data['password']),
    			'user_email'			=> $data['email'],
    			'group_id'				=> (int) $group_id,
    			'user_timezone'			=> (float) $config['board_timezone'],
    			'user_dst'				=> $config['board_dst'],
    			'user_lang'				=> basename($user->lang_name),
    			'user_type'				=> USER_NORMAL,
    			'user_actkey'			=> '',
    			'user_ip'				=> $user->ip,
    			'user_regdate'			=> time(),
    			'user_inactive_reason'	=> 0,
    			'user_inactive_time'	=> 0,
    		);
    		$user_id = user_add($user_row);
    		if ($user_id === false)
    		{
    			trigger_error('NO_USER', E_USER_ERROR);
    		}
    		$success = true;
    		$url_redirect = append_sid('./index.php');
    		$message = $user->lang['ACCOUNT_ADDED'] .  '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . $url_redirect . '">', '</a>');
    	}
    	else
    	{
    		$message_error = implode('<br />', $error);
    	}
    }
    $template->set_filenames(array('body' => 'register_body.html'));
    $template->assign_vars(array(
    	'S_SUCCESS'			=> $success,
    	'MESSAGE'			=> $message,
    	'MESSAGE_ERROR'		=> $message_error,
    	'U_REDIRECT'		=> $url_redirect,
    	'USERNAME'			=> $data['username'],
    	'PASSWORD'			=> $data['password'],
    	'PASSWORD_CONFIRM'	=> $data['password_confirm'],
    	'EMAIL'				=> $data['email'],
    	'EMAIL_CONFIRM'		=> $data['email_confirm']
    ));
    $template->display('body');
    ?>


4- Exporter votre base d'utilisateurs vers phpBB

Tout marche nickel, vos utilisateurs peuvent se connecter, les nouveaux peuvent s'inscrire, tout ça sans passer par le forum.
Mais voilà, vous aviez déjà une base de données d'utilisateurs avant de créer un forum phpBB, et vous aimeriez bien qu'ils n'aient pas à se réinscrire sur le forum.
voilà donc pas, à pas, un script pour exporter votre table d'utilisateurs.je l'ai testé sur une base de 800 utilisateurs, je ne garantis pas qu'au delà il n'y aura pas de time_out.
il est basique et sans fioritures, rien que les champs user, password et email. A vous de l'adapter en fonction de vos besoins
La seule condition pour qu'il marche c'est que la table se trouve, pas forcément dans la même base de données, mais en tout cas dans une base de données du même serveur
  • après avoir lancé la session phpBB, on va d'abord renseigner les items de votre table (vous aurez à remplacer les noms par ceux correspondant à votre configuration)
    • d'abord la base de données où se trouve votre table d'utilisateurs
      Code: Tout sélectionner
      $import_dbname = 'ma_base_de_donnees';

    • ensuite le nom de la table d'utilisateurs
      Code: Tout sélectionner
      $import_table = 'table_utilisateurs';

    • puis les noms des champs user, password et email
      Code: Tout sélectionner
      $champ_user = 'pseudo';
      $champ_password = 'password';
      $champ_email = 'email';
    • enfin, si (et seulement si) votre mot de passe est crypté en md5 ou en sha1, vous ajoutez cette ligne:
      Code: Tout sélectionner
      define('MD5_PASSWORD', true);
      de plus, s'il est crypté en sha1, vous aurez à effectuer les modifications de includes/auth/auth_db.php préconisées par Genova ici : aide-dev-adaptation-mods-phpbb3/sujet139404.html#p1064247
    • maintenant on crée une variable $import_db qui, si la base de données de vos utilisateurs est la même que celle de phpbb, sera une copie de $db, sinon elle pointera vers une nouvelle instance du moteur de bases de données:
      Code: Tout sélectionner
      if ($import_dbname == $dbname)
      A noter, dans ce cas, que vous aurez à nouveau à renseigner le mot de passe sql de votre serveur (car common.php l'a effacé après avoir lancé la connexion)
      {
      	$import_db = $db;
      }
      else
      {
      	$db_passwd = 'mon_mot_de_passe_sql';
      	$import_db = new $sql_db();
      	$import_db->sql_connect($dbhost, $dbuser, $dbpasswd, $import_dbname, $dbport, false, true);
      	unset($db_passwd);
      }
  • voilà, tous les renseignements sur votre base de données sont recueillis, et si besoin, une 2e connexion a été lancée. on va maintenant recueillir le n° du groupe par défaut. Comme ça sera toujours le même, il faut le faire avant la prochaine boucle
    Code: Tout sélectionner
    $group_name =  'REGISTERED';
    $sql = 'SELECT group_id
    		FROM ' . GROUPS_TABLE . "
    		WHERE group_name = '" . $db->sql_escape($group_name) . "'
    			AND group_type = " . GROUP_SPECIAL;
    $result = $db->sql_query($sql);
    $row = $db->sql_fetchrow($result);
    $db->sql_freeresult($result);
    if (!$row)
    {
    	trigger_error('NO_GROUP');
    }
    $group_id = $row['group_id'];

  • Voici maintenant lancée la requête et la boucle qui va parcourir la table de vos utilisateurs
    Code: Tout sélectionner
    $sql = "SELECT $champ_user, $champ_password, $champ_email FROM $import_table";
    $result = $import_db->sql_query($sql);
    while($row = $import_db->sql_fetchrow($result))
    {

    • A chaque passage de la boucle, on met dans le tableau $data le contenu des champs collectés
      Code: Tout sélectionner
      	$data = array(
      		'username'			=> utf8_normalize_nfc($row[$champ_user]),
      		'password'			=> $row[$champ_password],
      		'email'				=> strtolower($row[$champ_email]),
      	);

    • on envoie ce tableau à la validation (juste pour les champs username et user_email, car, pour les mots de passe, il faudrait augmenter dans le panneau d'admin la taille maximum des mots de passe en cas de cryptage md5
      Code: Tout sélectionner
      	$error = validate_data($data, array(
      		'username'			=> array(
      			array('string', false, $config['min_name_chars'], $config['max_name_chars']),
      			array('username', '')),
      		'email'				=> array(
      			array('string', false, 6, 60),
      			array('email')),
      	));
      	$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
    • si pas d'erreur, on envoie le tout à la fonction user_add. A noter que si le mot de passe est en clair, il passe au préalable par la fonction phpbb_hash et le champ user_convert est mis à 0, sinon le mot de passe est envoyé tel quel et le champ user_convert mis à 1 (pour indiquer à phpBB que ce mot de passe doit être converti de md5 ou sha1 vers le format phpBB 3.0.x)
      Code: Tout sélectionner
      	if (!sizeof($error))
      	{
      		$user_row = array(
      			'username'				=> $data['username'],
      			'user_password'			=> (defined('MD5_PASSWORD')) ? $data['password'] : phpbb_hash($data['password']),
      			'user_pass_convert'		=> (defined('MD5_PASSWORD')) ? 1 : 0,
      			'user_email'			=> $data['email'],
      			'group_id'				=> (int) $group_id,
      			'user_timezone'			=> (float) $config['board_timezone'],
      			'user_dst'				=> $config['board_dst'],
      			'user_lang'				=> basename($user->lang_name),
      			'user_type'				=> USER_NORMAL,
      			'user_actkey'			=> '',
      			'user_ip'				=> $user->ip,
      			'user_regdate'			=> time(),
      			'user_inactive_reason'	=> 0,
      			'user_inactive_time'	=> 0,
      		);
      		$user_id = user_add($user_row);
      		if ($user_id === false)
      		{
      			trigger_error('NO_USER', E_USER_ERROR);
      		}
    • toujours en cas de succès, le nom de l'utilisateur est ajouté à laiste des utilisateurs enregistrés avec succès
      Code: Tout sélectionner
      		$success_list[] = $data['username'];
      	}
    • en cas d'échec, il est ajouté à la liste des utilisateurs dont l'enregistrement à échoué (avec ajout du message d'erreur)
      Code: Tout sélectionner
      	else
      	{
      		$ignore_list[] = '<td>' . $data['username'] . '</td><td>' . implode('<br />', $error) . '</td>';
      	}
    • et on n'oublie pas l'accolade de fermeture de la boucle $db->sql_fetchrow
      Code: Tout sélectionner
      }
  • l'exportation est maintenant terminée, on affiche les résultats
    Code: Tout sélectionner
    echo '<html><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body>';
    if (sizeof($success_list))
    {
    	Echo '<b>Les utilisateurs suivants ont été importés dans la base phpbb avec succès:</b>' . implode(' - ', $success_list);
    }
    if (sizeof($ignore_list))
    {
    	echo '<hr /><b>les utilisateurs suivants n\'ont pu être enregistrés:</b><br />
    	<table border="1">
    	<tr><th>Pseudo</th><th>Raison de l\'échec</th>
    	<tr>' . implode('</tr><tr>', $ignore_list) . '</tr></table>';
    }
    echo '</body></html>';
    ?>

et voilà le script complet
Code: Tout sélectionner
<?php
define('IN_PHPBB', true);
$phpbb_root_path =  './phpBB3/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
require($phpbb_root_path . 'includes/functions_user.' . $phpEx);
$user->session_begin();
$auth->acl($user->data);
$user->setup('ucp');
$import_dbname = 'ma_base_de_donnees';
$import_table = 'table_utilisateurs';
$champ_user = 'pseudo';
$champ_password = 'password';
$champ_email = 'email';
define('MD5_PASSWORD', true);
if ($import_dbname == $dbname)
{
	$import_db = $db;
}
else
{
	$db_passwd = 'mon_mot_de_passe_mysql';
	$import_db = new $sql_db();
	$import_db->sql_connect($dbhost, $dbuser, $dbpasswd, $import_dbname, $dbport, false, true);
	unset($db_passwd);
}
$success_list=array();
$ignore_list = array();

$group_name =  'REGISTERED';
$sql = 'SELECT group_id
		FROM ' . GROUPS_TABLE . "
		WHERE group_name = '" . $db->sql_escape($group_name) . "'
			AND group_type = " . GROUP_SPECIAL;
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if (!$row)
{
	trigger_error('NO_GROUP');
}
$group_id = $row['group_id'];

$sql = "SELECT $champ_user, $champ_password, $champ_email FROM $import_table";
$result = $import_db->sql_query($sql);
while($row = $import_db->sql_fetchrow($result))
{
	$error = array();
	$data = array(
		'username'			=> utf8_normalize_nfc($row[$champ_user]),
		'password'			=> $row[$champ_password],
		'email'				=> strtolower($row[$champ_email]),
	);
	$error = validate_data($data, array(
		'username'			=> array(
			array('string', false, $config['min_name_chars'], $config['max_name_chars']),
			array('username', '')),
		'email'				=> array(
			array('string', false, 6, 60),
			array('email')),
	));
	$error = preg_replace('#^([A-Z_]+)$#e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '\\1'", $error);
	if (!sizeof($error))
	{
		$user_row = array(
			'username'				=> $data['username'],
			'user_password'			=> (defined('MD5_PASSWORD')) ? $data['password'] : phpbb_hash($data['password']),
			'user_pass_convert'		=> (defined('MD5_PASSWORD')) ? 1 : 0,
			'user_email'			=> $data['email'],
			'group_id'				=> (int) $group_id,
			'user_timezone'			=> (float) $config['board_timezone'],
			'user_dst'				=> $config['board_dst'],
			'user_lang'				=> basename($user->lang_name),
			'user_type'				=> USER_NORMAL,
			'user_actkey'			=> '',
			'user_ip'				=> $user->ip,
			'user_regdate'			=> time(),
			'user_inactive_reason'	=> 0,
			'user_inactive_time'	=> 0,
		);
		$user_id = user_add($user_row);
		if ($user_id === false)
		{
			trigger_error('NO_USER', E_USER_ERROR);
		}
		$success_list[] = $data['username'];
	}
	else
	{
		$ignore_list[] = '<td>' . $data['username'] . '</td><td>' . implode('<br />', $error) . '</td>';
	}
}
echo '<html><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body>';
if (sizeof($success_list))
{
	Echo '<b>Les utilisateurs suivants ont été importés dans la base phpbb avec succès:</b>' . implode(' - ', $success_list);
}
if (sizeof($ignore_list))
{
	echo '<hr /><b>les utilisateurs suivants n\'ont pu être enregistrés:</b><br />
	<table border="1">
	<tr><th>Pseudo</th><th>Raison de l\'échec</th>
	<tr>' . implode('</tr><tr>', $ignore_list) . '</tr></table>';
}
echo '</body></html>';
?>



5-A Créer une page de news - version simple
mis à jour le 26/09/2011

Vous avez maintenant tout ce qu'il faut pour gérer les connexions et les inscriptions de vos utilisateurs.
maintenant vous aimeriez bien afficher à la page d'accueil de votre site, les dernières nouvelles de votre site.
voilà un script nommé news.php qui va afficher la même chose que viewforum.php sauf que ça sera les 10 derniers sujets de tous les forums (ou d'un forum particulier si vous le lancez par news.php?forum_id=2)
  • après avoir lancé la session.phpbb on recueille d'abord les données de l'id du forum (dans le cas du choix de tous les forums, on ne listera que ceux que l'utilisateur est en droit de lire)
    Code: Tout sélectionner
    $forum_id = request_var('forum_id', 0);
    $where = ($forum_id) ? " WHERE forum_id=$forum_id" : ' WHERE' .$db->sql_in_set('forum_id', array_keys($auth->acl_getf('f_read', true))) ;

  • on lance la requête sql listant les 10 derniers sujets (on élimine les topics qui ont été déplacés et qui gardent une trace dans le forum d'origine, ce qui se voit sur le champ topic_status)
    Code: Tout sélectionner
    $sql = 'SELECT forum_id,topic_id, topic_time, topic_title, topic_views, topic_replies, topic_poster, topic_first_poster_name, topic_first_poster_colour, topic_last_post_id, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour, topic_last_post_time
    	FROM ' . TOPICS_TABLE . 
    		$where . '
    		AND topic_status <> ' . ITEM_MOVED . ' 
    		ORDER BY topic_time DESC
    		LIMIT 0 , 10';
    $result = $db->sql_query($sql);
  • on affiche un entete simplifié, un style pour l'entête du tableau, et le dit entête
    Code: Tout sélectionner
    ?>
    <html>
    <head>
    	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    	<title>Les dernières news</title>
    	<style type="text/css">
    		th{
    			background-color: #0066FF;
    			color: #FFFF99;
    		}
    	</style>
    </head>
    <body>
    <table width="100%">
    	<tr>
    	<th >Sujets</th>
    <th>Réponses</th>
    <th>Vus</th>
    <th>Dernier message</th>
    </tr>
    <?php
  • on prépare un compteur, afin d'avoir une couleur différente une ligne sur 2
    Code: Tout sélectionner
    $i = 0:
  • on lance la boucle d'exploration du résultat de la requête
    Code: Tout sélectionner
    while($row = $db->sql_fetchrow($result))
    {
  • on recueille le n° et l'url du sujet
    Code: Tout sélectionner
    	$topic_id = $row['topic_id'];
    	$view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . (($row['forum_id']) ? $row['forum_id'] : $forum_id) . '&amp;t=' . $topic_id);
  • on change de couleur une ligne sur 2
    Code: Tout sélectionner
    	$row_colour = ($i % 2) ? '#FFFFCC' : '#99FFFF';
    	echo '<tr bgcolor="' . $row_colour .'">';
  • l'adresse url du sujet (avec utilisation de la fonction censor_text qui va remplacer les mots éventuellement censurés)
    Code: Tout sélectionner
    	echo '<td>';
    	echo '<a href="' . $view_topic_url . '">' . censor_text($row['topic_title']) . '</a><br />';
  • Les coordonnées de l'auteur et la couleur correspondant à son groupe on utilise pour ça la fonction get_username_string qui retourne un lien vers le profil de l'utilisateur)
    Code: Tout sélectionner
    	echo $user->lang['POST_BY_AUTHOR'] . '&nbsp;' . get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']);
  • la date de publication du sujet
    Code: Tout sélectionner
    	echo '&nbsp;' . $user->lang['POSTED_ON_DATE'] . '&nbsp;' . $user->format_date($row['topic_time']) . '</td>';
  • le nombre de réponses et de vues du sujet
    Code: Tout sélectionner
    	echo '<td>' . $row['topic_replies'] . '</td>';
    	echo '<td>' . $row['topic_views'] . '</td>';
  • les coordonnées de l'auteur de la dernière réponse
    Code: Tout sélectionner
    	echo '<td>' . $user->lang['POST_BY_AUTHOR'] . '&nbsp;' . get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']);
  • un lien vers la dernière réponse contenue dans une petite icône
    Code: Tout sélectionner
    	echo '<a href="' . $view_topic_url . '&amp;p=' . $row['topic_last_post_id'] . '#p' . $row['topic_last_post_id'] . '">' . '&nbsp;' . $user->img('icon_topic_latest', 'VIEW_LATEST_POST') . '</a><br />';
  • la date de publication de la dernière réponse
    Code: Tout sélectionner
    	echo $user->lang['POSTED_ON_DATE'] . $user->format_date($row['topic_last_post_time']) . '</td>';
  • on ferme la ligne, on incrémente le compteur de boucle et on ferme la boucle
    Code: Tout sélectionner
    	echo '</tr>';
    	$i++;
    }
et voilà le script complet
Code: Tout sélectionner
<?php
define('IN_PHPBB', true);
$phpbb_root_path =  './phpBB3/';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
$user->session_begin();
$auth->acl($user->data);
$user->setup();
$forum_id = request_var('forum_id', 0);
$where = ($forum_id) ? " WHERE forum_id=$forum_id" : ' WHERE' .$db->sql_in_set('forum_id', array_keys($auth->acl_getf('f_read', true)));
$sql = 'SELECT forum_id,topic_id, topic_time, topic_title, topic_views, topic_replies, topic_poster, topic_first_poster_name, topic_first_poster_colour, topic_last_post_id, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour, topic_last_post_time
	FROM ' . TOPICS_TABLE . 
		$where . '
		AND topic_status <> ' . ITEM_MOVED . ' 
		ORDER BY topic_time DESC
		LIMIT 0 , 10';
$result = $db->sql_query($sql);
?>
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	<title>Les dernières news</title>
	<style type="text/css">
		th{
			background-color: #0066FF;
			color: #FFFF99;
		}
	</style>
</head>
<body>
<table width="100%">
	<tr>
	<th >Sujets</th>
<th>Réponses</th>
<th>Vus</th>
<th>Dernier message</th>
</tr>
<?php
$i=0;
while($row = $db->sql_fetchrow($result))
{
	$topic_id = $row['topic_id'];
	$view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . (($row['forum_id']) ? $row['forum_id'] : $forum_id) . '&amp;t=' . $topic_id);
	$row_colour = ($i % 2) ? '#FFFFCC' : '#99FFFF';
	echo '<tr bgcolor="' . $row_colour .'">';
	echo '<td>';
	echo '<a href="' . $view_topic_url . '">' . censor_text($row['topic_title']) . '</a><br />';
	echo $user->lang['POST_BY_AUTHOR'] . '&nbsp;' . get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']);
	echo '&nbsp;' . $user->lang['POSTED_ON_DATE'] . '&nbsp;' . $user->format_date($row['topic_time']) . '</td>';
	echo '<td>' . $row['topic_replies'] . '</td>';
	echo '<td>' . $row['topic_views'] . '</td>';
	echo '<td>' . $user->lang['POST_BY_AUTHOR'] . '&nbsp;' . get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']);
	echo '<a href="' . $view_topic_url . '&amp;p=' . $row['topic_last_post_id'] . '#p' . $row['topic_last_post_id'] . '">' . '&nbsp;' . $user->img('icon_topic_latest', 'VIEW_LATEST_POST') . '</a><br />';
	echo $user->lang['POSTED_ON_DATE'] . $user->format_date($row['topic_last_post_time']) . '</td>';
	echo '</tr>';
	$i++;
}
?>
</table>
</body>
</html>



5-B Créer une page de news - version templatée

  • news_body.html
    Rien de particulier à signaler , sinon que nous utilisons le compteur de boucles pour afficher une couleur différente les pages paires et impaires
    Code: Tout sélectionner
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
    <head>
    	<title>NEWS</title>
    	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    		<style type="text/css">
    		th{
    			background-color: #0066FF;
    			color: #FFFF99;
    		}
    	</style>
    </head>
    <body>
    <table width="100%">
    	<tr>
    		<th >{L_TOPICS}</th>
    		<th>{L_REPLIES}</th>
    		<th>{L_VIEWS}</th>
    		<th>{L_LAST_POST}</th>
    	</tr>
    	<!-- BEGIN topicrow -->
    	<tr bgcolor="<!-- IF topicrow.S_ROW_COUNT is even -->#FFFFCC<!-- ELSE -->#99FFFF<!-- ENDIF -->">
    		<td>
    			<a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a><br />
    			{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR} {L_POSTED_ON_DATE} {topicrow.FIRST_POST_TIME}
    		</td>
    		<td>{topicrow.REPLIES}</td>
    		<td>{topicrow.VIEWS}</td>
    		<td>
    			{L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR}
    			<a href="{topicrow.U_LAST_POST}">{LAST_POST_IMG}</a> <br />{L_POSTED_ON_DATE} {topicrow.LAST_POST_TIME}
    		</td>
    	</tr>
    	<!-- END topicrow -->
    </table>
    </body>
    </html>

  • côté php
    Code: Tout sélectionner
    <?php
    define('IN_PHPBB', true);
    $phpbb_root_path =  './phpBB3/';
    $phpEx = substr(strrchr(__FILE__, '.'), 1);
    include($phpbb_root_path . 'common.' . $phpEx);
    $user->session_begin();
    $auth->acl($user->data);
    $user->setup();
    $forum_id = request_var('forum_id', 0);
    $where = ($forum_id) ? " WHERE forum_id=$forum_id" : ' WHERE' .$db->sql_in_set('forum_id', array_keys($auth->acl_getf('f_read', true)));
    $sql = 'SELECT forum_id,topic_id, topic_time, topic_title, topic_views, topic_replies, topic_poster, topic_first_poster_name, topic_first_poster_colour, topic_last_post_id, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour, topic_last_post_time
    	FROM ' . TOPICS_TABLE . 
    		$where . '
    		AND topic_status <> ' . ITEM_MOVED . ' 
    		ORDER BY topic_time DESC
    		LIMIT 0 , 10';
    $result = $db->sql_query($sql);
    $template->set_filenames(array('body' => 'news_body.html'));
    $template->assign_vars(array(
    	'LAST_POST_IMG'				=> $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
    ));
    while($row = $db->sql_fetchrow($result))
    {
    	$topic_id = $row['topic_id'];
    	$view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . (($row['forum_id']) ? $row['forum_id'] : $forum_id) . '&amp;t=' . $topic_id);
    	$template->assign_block_vars('topicrow', array(
    		'FIRST_POST_TIME'	=> $user->format_date($row['topic_time']),
    		'LAST_POST_AUTHOR'	=> get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
    		'LAST_POST_TIME'	=> $user->format_date($row['topic_last_post_time']),
    		'REPLIES'			=> $row['topic_replies'],
    		'TOPIC_AUTHOR'		=> get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
    		'TOPIC_TITLE'		=> censor_text($row['topic_title']),
    		'U_LAST_POST'		=> $view_topic_url . '&amp;p=' . $row['topic_last_post_id'] . '#p' . $row['topic_last_post_id'],
    		'U_VIEW_TOPIC'		=> $view_topic_url,
    		'VIEWS'				=> $row['topic_views'],
    	));
    }
    $template->display('body');
    ?>


6 - Modifier le gestionnaire des messages d'erreur
Avoir bâti son site, tout bô, tout nickel, avec gestion des utilisateurs et une belle page de news, et bing, un message d'erreur nous ramène au forum, avec enntête, lien vers l'index du forum.... c'est trés frustrant.

voici comment sont gérés les messages d'erreur:
dans common.php, vous avez cette ligne:
Code: Tout sélectionner
set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler');

ça veut dire que sauf si la constante PHPBB_MSG_HANDLER est définie, toutes les erreurs d'exécution (notamment celles déclenchées par l'appel à triger_error() ) entraineront l'exécution de la fonction msg_handler (qui se trouve dans includes/functions.php)
Je n'ai pas la prétention de vous faire réécrire entièrement ce gestionnaire, mais juste de modifier entêtes et bas de page quand l'erreur est déclenchée par une page de votre site.
Plutôt que de modifier la fonction elle-même, il est préférable d'en faire une copie que nous pourrons alors modifier à volonté.
ouvrez includes/functions.php et cherchez
Code: Tout sélectionner
function msg_handler($errno, $msg_text, $errfile, $errline)

copier le code à partir de cette ligne, jusqu'à, (compris)
Code: Tout sélectionner
	// If we notice an error not handled here we pass this back to PHP by returning false
	// This may not work for all php versions
	return false;
}

et collez-le dans le même fichier juste avant ?> (ou collez-le dans un fichier personnel, à condition qu'il soit inclus dans chacune de vos page ayant lancé une session phpbb.
dans le code que vous avez collé (pas dans le code d'origine, hé ?)
remplacez
Code: Tout sélectionner
function msg_handler($errno, $msg_text, $errfile, $errline)

par
Code: Tout sélectionner
function mon_msg_handler($errno, $msg_text, $errfile, $errline)

le code sur lequel nous aurons à travailler est celui-ci:
Code: Tout sélectionner
			if (!defined('HEADER_INC'))
			{
				if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
				{
					adm_page_header($msg_title);
				}
				else
				{
					page_header($msg_title);
				}
			}

			$template->set_filenames(array(
				'body' => 'message_body.html')
			);

			$template->assign_vars(array(
				'MESSAGE_TITLE'		=> $msg_title,
				'MESSAGE_TEXT'		=> $msg_text,
				'S_USER_WARNING'	=> ($errno == E_USER_WARNING) ? true : false,
				'S_USER_NOTICE'		=> ($errno == E_USER_NOTICE) ? true : false)
			);

			// We do not want the cron script to be called on error messages
			define('IN_CRON', true);

			if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
			{
				adm_page_footer();
			}
			else
			{
				page_footer();
			}

nous supposerons que votre entête personnel est appelé dans vos pages par
Code: Tout sélectionner
include('header.php');

et le bas de page par
Code: Tout sélectionner
include('footer.php');

si vos entêtes et bas de page sont affichés différemment, il vous faudra rectifier le code en conséquence
  • remplacez
    Code: Tout sélectionner
    			if (!defined('HEADER_INC'))
    			{
    				if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
    				{
    					adm_page_header($msg_title);
    				}
    				else
    				{
    					page_header($msg_title);
    				}
    			}
    par
    Code: Tout sélectionner
    			if (!defined('HEADER_INC'))
    			{
    				include('header.php');
    			}

    et
    Code: Tout sélectionner
    			if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
    			{
    				adm_page_footer();
    			}
    			else
    			{
    				page_footer();
    			}
    par
    Code: Tout sélectionner
    			include('footer.php');


  • ce code:
    Code: Tout sélectionner
    			$template->set_filenames(array(
    				'body' => 'message_body.html')
    			);
    
    			$template->assign_vars(array(
    				'MESSAGE_TITLE'		=> $msg_title,
    				'MESSAGE_TEXT'		=> $msg_text,
    				'S_USER_WARNING'	=> ($errno == E_USER_WARNING) ? true : false,
    				'S_USER_NOTICE'		=> ($errno == E_USER_NOTICE) ? true : false)
    			);
    doit être laissé tel quel, si vous utilisez les templates dans toutes vos pages, mais ça suppose que vous mettiez
    Code: Tout sélectionner
    $template->display('body');
    dans votre footer.php.

    si vous n'utilsez pas les templates, alors remplacez ce code par
    Code: Tout sélectionner
    			echo "<h2>$msg_title</h2>
    			     <p>$msg_text</p>";

  • Voilà, votre gestionnaire d'erreur est terminé, il vous reste à le rendre opérationnel:
    • d'abord placez dans votre header.php
      Code: Tout sélectionner
      define('HEADER_INC, true);
      ça évitera que le gestionnaire d'erreurs n'affiche une 2e fois l'entête si celui-ci est déjà affiché quand survient l'erreur
    • et enfin placez dans toutes les pages de votre site lançant une session phpBB:
      Code: Tout sélectionner
      define('PHPBB_MSG_HANDLER', 'mon_msg_handler');
      et ceci juste après
      Code: Tout sélectionner
      define('IN_PHPBB', true);
      ou tout au moins AVANT
      Code: Tout sélectionner
      include($phpbb_root_path . 'common.' . $phpEx);


7a- Ajouter un captcha au formulaire de connexion version non templatée

En cas de 3 erreurs de connexion, le script ne marche plus car il attend un captcha.
reprenez mon_login.php (version non templatée) et cherchez:
Code: Tout sélectionner
   $result = $auth->login($username, $password, $autologin, $viewonline, $admin);

Ajoutez AVANT
Code: Tout sélectionner
	if (!class_exists('phpbb_captcha_factory'))
	{
		include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
	}


Cherchez
Code: Tout sélectionner
	if ($result['status'] != LOGIN_SUCCESS)
	{
		$err = $user->lang[$result['error_msg']];
		if ($result['error_msg'] == 'LOGIN_ERROR_USERNAME' || $result['error_msg'] == 'LOGIN_ERROR_PASSWORD')
		{
			$err = (!$config['board_contact']) ? sprintf($user->lang[$result['error_msg']], '', '') : sprintf($user->lang[$result['error_msg']], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>');
		}


ajoutez après
  • pour les versions de phpBB antérieures à 3.0.6
    Code: Tout sélectionner
    		if ($result['status'] == LOGIN_ERROR_ATTEMPTS)
    		{
    			$sql = 'DELETE FROM ' . CONFIRM_TABLE . "
    					WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
    						AND confirm_type = " . CONFIRM_LOGIN;
    			$db->sql_query($sql);
    			$code = gen_rand_string(mt_rand(5, 8));
    			$confirm_id = md5(unique_id($user->ip));
    			$seed = hexdec(substr(unique_id(), 4, 10));
    			$seed -= 0x7fffffff * floor($seed / 0x7fffffff);
    			$sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array(
    					'confirm_id'	=> (string) $confirm_id,
    					'session_id'	=> (string) $user->session_id,
    					'confirm_type'	=> (int) CONFIRM_LOGIN,
    					'code'			=> (string) $code,
    					'seed'			=> (int) $seed)
    				);
    			$db->sql_query($sql);
    			$confirm_code = true;
    			$confirm_image='<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=confirm&amp;id=' . $confirm_id . '&amp;type=' . CONFIRM_LOGIN) . '" alt="" title="" />';
    		}
  • A partir de la version 3.0.6
    Code: Tout sélectionner
    		if ($result['status'] == LOGIN_ERROR_ATTEMPTS)
    		{
    			$captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
    			$captcha->init(CONFIRM_LOGIN);
    			$confirm_id = $captcha->confirm_id;
    			$confirm_code = true;
    			$confirm_image='<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=confirm&amp;confirm_id=' . $confirm_id . '&amp;type=' . CONFIRM_LOGIN) . '" alt="" title="" />';
    		}
cherchez
Code: Tout sélectionner
      <tr>
         <td align="right">Mot de passe:</td>
         <td><input type="password" tabindex="2" name="password" size="25" />
         <br /><a href="<?php echo append_sid("{$phpbb_root_path}ucp.$phpEx?mode=sendpassword"); ?>">J’ai oublié mon mot de passe</a>
         </td>
      </tr>

ajoutez après
Code: Tout sélectionner
<?php
if ($confirm_code)
{
?>
	<tr>
		<td><?php echo $user->lang['CONFIRM_CODE'] . '<br />' . $user->lang['CONFIRM_CODE_EXPLAIN']; ?></td>
		<td><input type="hidden" name="confirm_id" value="<?php echo $confirm_id; ?>" /><?php echo $confirm_image; ?></td>
	</tr>
	<tr>
		<td>&nbsp;</td>
		<td><input type="text" name="confirm_code" id="confirm_code" size="8" maxlength="8" /></td>
	</tr>
<?php
}
?>