Création du système de commentaires

Attention, depuis PHP 5.5.0, certaines extensions SQL sans doute utilisées dans ce tutoriel peuvent être obsolètes et seront supprimées dans le futur, vous devez donc adapter les codes! Exemples ici.
Nous allons à présent créer un système de commentaires qui va permettre à nos visiteurs d'interagir avec le site.

Comme d'habitude, nous partons d'un formulaire et ce formulaire doit permettre d’enregistrer :
  • Le pseudo.
  • Le mail du posteur.
  • Le commentaire déposé.
  • La date du commentaire.
  • L'ip du posteur.
  • Le suivit des commentaires.
  • La "validation" du commentaire.
Explications :
Nous enregistrons l'ip du posteur pour nous permettre, si besoin, de bannir l'adresse ip.
Le suivit du commentaire permet au posteur de recevoir par mail une notification si un autre commentaire est déposé suite au sien.
La validation du commentaire est par défaut sur zéro et permet de mettre en attente le commentaire afin d'être contrôlé et validé par l'admin..

Nous allons également intégrer un captcha pour éviter le spam à gogo, le logiciel Ckeditor pour le dépôt du commentaire et un masquage du formulaire pour éviter la répétition d’envoi du formulaire.

Nous créons une nouvelle page vide que l'on va nommer "commentaire.php". Pour éviter un tutoriel interminable, j'intègre dans le code ci-dessous toutes les variables d'erreurs ainsi que le logiciel Ckeditor pour le champ du commentaire :
<span class="commentaire-thematique">Laisser un commentaire</span>
<div class="cadre">
<?php if(isset($message_ok)) echo $message_ok;
//On masque le formulaire
if($masquer_formulaire == 0) {
    ?>
    <form class="form" action="#ok" method="post">
    <?php if(isset($alerte_pseudo_admin)) echo $alerte_pseudo_admin;?>
    <?php if(isset($alerte_pseudo)) echo $alerte_pseudo;?>
    <label for="pseudo">Pseudo:</label>
    <input name="pseudo" size="22" value="<?php if (!empty($_POST["pseudo"])) { echo stripcslashes(htmlspecialchars($_POST["pseudo"],ENT_QUOTES)); } ?>" type="text"/>
    <br/>
    <?php if(isset($alerte_email)) echo $alerte_email;?>
    <?php if(isset($alerte_email_bis)) echo $alerte_email_bis;?>
    <label for="email">Email:</label>
    <input name="email" size="22" value="<?php if (!empty($_POST["email"])) { echo stripcslashes(htmlspecialchars($_POST["email"],ENT_QUOTES)); } ?>" type="text"/>
    <br/>
    <script type="text/javascript" src="http://<?php echo $_SERVER['HTTP_HOST'];?>/ckeditor/ckeditor.js"></script>
    <?php if(isset($alerte_commentaire)) echo $alerte_commentaire;?>
    <textarea name="commentaire" rows="10" cols="50"><?php
    if (!empty($_POST["commentaire"])) {
        echo stripcslashes(htmlspecialchars($_POST["commentaire"],ENT_QUOTES));
    }
    ?></textarea>
    <script type="text/javascript">
CKEDITOR.replace( 'commentaire',
    {
        toolbar :
        [
    ['Link','-','NumberedList','BulletedList','-','Blockquote','-','Image','Smiley','-','Undo','Redo'],
        ]
    });
</script>
 
    <br/>
    <?php if(isset($alerte_suivre_sujet)) echo $alerte_suivre_sujet;?>
    <label for="suivre_sujet">Suivre les réponses :</label>
    <select name="suivre_sujet">
    <option value="">Sélectionnez</option>
    <option value="Non"<?php if(isset($suivre_sujet) && $suivre_sujet=="Non") { echo "selected='selected'";}?>>Non</option>
    <option value="Oui"<?php if(isset($suivre_sujet) && $suivre_sujet=="Oui") { echo "selected='selected'";}?>>Oui</option>
    </select>
    <br/>
    <?php
    if (isset($alerte_capcha_vide)) echo $alerte_capcha_vide;
    if (isset($alerte_capcha_erreur)) echo $alerte_capcha_erreur;
    ?>
    <label for="capcha">Captcha :</label>
    <input name="capcha" size="22" value="<?php if (!empty($_POST["capcha"])) { echo stripcslashes(htmlspecialchars($_POST["capcha"],ENT_QUOTES)); } ?>" type="text"/><span class="ok"><?php echo $pass;?></span>
    <input name="verification_capcha" size="22" value="<?php echo $pass;?>" type="hidden"/>
<br/>
    <label for="Valider">Action :</label>
    <input name="Valider" value="Valider" type="submit"/>
    <input name="Effacer" value="Effacer" type="reset"/>
    <br/>
    </form>
    </div>
Le captcha est généré via une fonction "function generer_code()" que nous verrons un peut plus tard.
Nous allons maintenant programmer la partie PHP et le code va commencer au dessus du formulaire.

Dans un premier temps, on interdit l'accès directe au fichier :
<?php
//Si le système de commentaire est affiché directement, on stop tout!
if(basename($_SERVER["SCRIPT_NAME"])=="commentaire.php"){
    echo '<b>La ressource demandé est inaccessible!</b>';
    exit();
}
Puis on initialise le masquage du formulaire :
//initialisation du masquage du formulaire
$masquer_formulaire = 0;
L'action de validation du formulaire a été effectué, on place chaque champ du formulaire dans des variables :
if(isset($_POST["Valider"]))
{
    //Variables
    $pseudo = htmlspecialchars(stripcslashes($_POST["pseudo"]));
    $email = htmlspecialchars(stripcslashes($_POST["email"]));
    $commentaire = htmlspecialchars(stripcslashes($_POST["commentaire"]));
    $suivre_sujet = $_POST["suivre_sujet"];
    $capcha = htmlspecialchars(stripcslashes($_POST["capcha"]));
    $verification_capcha = htmlspecialchars(stripcslashes($_POST["verification_capcha"]));
    $ip = getIp();
    $timestamp = time();
    $validation = 0;
L'ip est contrôlé via une fonction "function getIp()" que nous verrons un peut plus tard.
Avant de contrôler et d'enregistrer quoi que ce soit, nous vérifions que l'auteur du commentaire ne soit pas banni et si tel est le cas, on lui refuse le dépôt d'un commentaire :
    //L'auteur du poste est il banni (2)
    $ban = mysql_query("SELECT email,ip FROM COMMENTAIRE WHERE validation = '2' AND (ip = '".mysql_real_escape_string($ip)."' OR email = '".mysql_real_escape_string($email)."')");
    //Si le résultat est différent de zéro, c'est que l'auteur est banni
    if(mysql_num_rows($ban) != 0)
    {
        echo '<div class="erreur"><a name="ok"></a>Le système de commentaires vous est refusé!</div>';
    }
Ce contrôle passé, on vérifie chaque champ du formulaire :
    //Le pseudo est il celui de l'admin?
    else if($pseudo == $pseudo_admin){
        $alerte_pseudo_admin ='<div class="erreur"><a name="ok"></a>Vous ne pouvez pas utiliser ce pseudo. Merci d\'en choisir un autre.</div>';
    }
    //Le pseudo est vide
    else if(empty($pseudo)){
        $alerte_pseudo ='<div class="erreur"><a name="ok"></a>Vous n\'avez pas saisie votre pseudo.</div>';
    }
    //L'adresse mail est vide
    else if(empty($email)){
        $alerte_email ='<div class="erreur"><a name="ok"></a>Vous n\'avez pas saisie votre email.</div>';
    }
    //on contrôle la validité de l’email
    else if (!preg_match("#^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,4}$#",$email))
    {
        $alerte_email_bis ='<div class="erreur"><a name="ok"></a>Votre Email semble ne pas être valide.</div>';
    }
    //Le commentaire est vide
    else if(empty($commentaire)){
        $alerte_commentaire ='<div class="erreur"><a name="ok"></a>Vous n\'avez pas saisie votre commentaire.</div>';
    }
    //Le posteur na pas sélectionné son choix
    else if(empty($suivre_sujet)){
        $alerte_suivre_sujet ='<div class="erreur"><a name="ok"></a>Vous n\'avez pas sélectionné votre choix.</div>';
    }
    //Le captcha est vide
    else if(empty($capcha)){
        $alerte_capcha_vide ='<div class="erreur"><a name="ok"></a>Vous n\'avez pas saisie le captcha.</div>';
    }
    //Le captcha est incorrecte
        else if($capcha != $verification_capcha){
        $alerte_capcha_erreur ='<div class="erreur"><a name="ok"></a>Le captcha que vous avez saisie est incorrecte.</div>';
    }
Si tout est "ok", on enregistre les données :
    //Tout est ok
    else {
        // on enregistre les données
        $result = mysql_query("INSERT INTO COMMENTAIRE VALUES ( '', '".mysql_real_escape_string($id)."', '".mysql_real_escape_string($pseudo)."', '".mysql_real_escape_string($email)."', '".mysql_real_escape_string($commentaire)."', '".mysql_real_escape_string($ip)."', '".mysql_real_escape_string($timestamp)."', '".mysql_real_escape_string($validation)."', '".mysql_real_escape_string($suivre_sujet)."' ) ");
Si il y a une erreur, on l'indique :
        //Si il y a une erreur
        if (!$result) {
            die('Requête invalide : ' . mysql_error());
        }
L'enregistrement c'est bien passé, on envoie un mail au webmaster pour le prévenir qu'un commentaire est en attente de validation :
        //pas d'erreur d'enregistrement
        else {
            //on informe le webmaster qu'un commentaire à été déposé
            //email de celui qui envoie
            $webmaster = $adresse_email;
            //email de celui qui reçoit
            $a_qui_j_envoie = $adresse_email;
            //sujet
            $subject = "Commentaire en attente";
            //message  
            $msg  = "Bonjour <br/><br/>";
            $msg .= "Un commentaire concernant l'article « ".$titre." » est en attente de validation sur votre site <a href=\"http://".$_SERVER['HTTP_HOST']."\">http://".$_SERVER['HTTP_HOST']."</a><br/>";
            $msg .= "Date et heure :\tle ".convertit_timestamp_en_date("$timestamp")."\n";
            //permet de savoir qui envoie le mail et d'y répondre
            $mailheaders = "From: $webmaster\n";
            $mailheaders .= "MIME-version: 1.0\n";
            $mailheaders .= "Content-type: text/html; charset= iso-8859-1\n";
            //on envoie l'email
            mail($a_qui_j_envoie, $subject, $msg, $mailheaders);
        }
La date envoyé dans le mail utilise une fonction nommé "convertit_timestamp_en_date()" que nous verrons un peut plus tard.
Le mail est envoyé, on informe l'internaute que son commentaire est en attente de validation :
        //on informe que le message est enregistré
        $message_ok = '<div class="ok"><a name="ok"></a>Votre commentaire est en attente de validation. Merci de votre participation ;)! Vous allez être redirigé automatiquement d\'ici quelques secondes.<img src="http://'.$_SERVER['HTTP_HOST'].'/images/loading.gif" alt="Loading"/></div>';
On masque le formulaire et on redirige le posteur vers la page en cours pour éviter la répétition d’envoi du formulaire :
        //on masque le formulaire
        $masquer_formulaire=1;
        //on redirige vers la page en cours pour éviter la répétition d’envoi du formulaire
        echo '<script> function redirection(page){ window.location=page; } setTimeout(\'redirection("'.$_SERVER['REQUEST_URI'].'")\',8000); </script>';
Puis on referme tout :
        //on ferme else
    }
    //Fermeture de if(isset($_POST["Valider"]))
}
?>
On va maintenant afficher les commentaire si il y a et nous allons coder cette partie sous le formulaire.

D abord, on ferme le masquage du formulaire dont le code est situé pour rappel juste avant le début du formulaire :
<?php
//On ferme if($masquer_formulaire == 0)
}
On va à présent chercher tout les commentaires qui correspond à l'article et qui sont validés par l'admin. :
//On va chercher les commentaires en rapport avec la page
$affiche_commentaire = mysql_query("SELECT id,pseudo,commentaire,date FROM COMMENTAIRE WHERE id_page='".mysql_real_escape_string($id)."' AND validation='1' ORDER BY id ASC");
//Si il y a quelque chose, on affiche
if(mysql_num_rows($affiche_commentaire) != 0)
{
    while($affiche = mysql_fetch_array($affiche_commentaire))
    {
        //On change la couleur du cadre des réponses de l'admin
        if($affiche['pseudo']==$pseudo_admin){
            echo '<div class="cadre-commentaire-admin">';
        }
        else{
            echo '<div class="cadre-commentaire">';
        }
        echo '<a name="'.$affiche['id'].'"></a> <b>'.$affiche['pseudo'].' <span class="date">'.convertit_date($affiche['date']).'</span></b><br/><br/>'.nl2br($affiche['commentaire']).'</div>';
    }
}
Explications :
La variable $id est une variable située dans le fichier "page1.php" et qui fait référence à l'id de l'article.
La class CSS utilisé dans l'affichage des commentaires varie en fonction du posteur afin d'afficher une couleur différente si c'est l'admin. qui répond (voir la feuille de style).
On utilise une ancre dans l'affichage des commentaires afin d'envoyer les personnes qui suivent le sujet directement sur le dernier commentaire. Pour rappel, les "adhérents" reçoivent un mail à chaque commentaire déposés et ce mail contient entre autre l'adresse exacte du dernier commentaire (ancre).

Si il ni y a aucun commentaire, on informe l'internaute :
else{
    echo '<div class="cadre-commentaire-admin"><b>'.$pseudo_admin.' <span class="date">'.convertit_date(time()).'</span></b><br/><br/>Aucun commentaire pour le moment concernant le sujet « <strong>'.$titre.'</strong> »!</div>';
}
?>
Voila, le système de commentaires est finit, passons maintenant à l'inclusion des fonctions utilisés.

On ouvre le fichier des fonctions.

Fonction pour contrôler l'adresse ip du posteur :
//Fonction pour l'ip
function getIp()
{
    if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
    {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    elseif(isset($_SERVER['HTTP_CLIENT_IP']))
    {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    else
    {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}
Fonction pour générer un captcha aléatoire :
//Fonction pour générer un captcha aléatoire
function generer_code($taille)
{
    $caracteres = array("a", "b", "c", "d", "e", "f","g", "h", "i", "j", "k", "l","m",
    "n", "o", "p", "q", "r","s", "t", "u", "v", "w", "x","y","z", 0, 1, 2, 3, 4, 5, 6,
    7, 8, 9);
    $caracteres_aleatoires = array_rand($caracteres, $taille);
    $pass = "";
    foreach($caracteres_aleatoires as $i)
    {
        $pass .= $caracteres[$i];
    }
        return $pass;   
}
$pass = generer_code(8);
Fonction pour la date :
//fonction pour convertir un timestamp en date (formulaire de contacte + commentaire) ok
function convertit_timestamp_en_date($timestamp_actuel) {
    return date("j-m-Y @ H:i:s", $timestamp_actuel);
}
Système de commentaire du CMS spécial free.fr
Voir/déposer un commentaire (0) | Signaler un problème