Fonction commentaire PHP : Ajoutez des commentaires à vos articles

Article ajouté le 09/01/2019

A la base, lorsqu'on souhaite créer un site de type blog (Constitué essentiellement d'articles et d'un espace commentaire associé), on utilise un CMS de type Wordpress. Cela nous évite de réinventer la roue et donc de perdre du temps à redévelopper entièrement ce module.

Dans mon cas, je possédais au départ un site vitrine qui ne proposait que des simples contenus. Je n'ai donc pas eu besoin de ce genre de module. Cependant, mon site à très vite évolué et j'ai donc du concevoir une fonction simple qui allait permettre à un grand nombre des pages de faire réagir les visiteurs sur le contenus.

En revanche, les pages étaient déjà créées. J'ai donc eu un premier souci vis à vis des identifiants permettant d'associer une page à des commentaires en base de données.

Pour cette base, j'ai été au plus efficace en récupérant l'url de la page et en m'en servant en tant qu'identifiant pour l'association de ses commentaires.

Je vous passe les détails techniques et j'en viens tout de suite au but (Oui c'est un peu expédié) : Je vous présente ici mon propre module de commentaires qui ressemble un peu aux commentaires qu'on retrouve sur Youtube par exemple.

Update du 19/11/2019 : Prise en compte de vos commentaires (Ajout CSS, connexion BDD, appel JQuery et URL courrante). N'hésitez pas si vous avez d'autres critiques.

Le code PHP / HTML à insérer sur vos pages

<?php
	$db = new PDO('mysql:host=SERVER;dbname=BDD;charset=utf8mb4', 'USER', 'PASSWORD');
	$currenturl = strtolower('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);

	// Fonctions de chargement des commentaires

	function commentaires($url, $id_commentaire=0)
	{
		global $db;
	
		$i=0;
		$commentaires = '';
		$tcolor = ['blue','green','orange','purple','gray','red'];
		
		$sql = "SELECT id_commentaire, nom, commentaire, email, date FROM p3x_commentaire WHERE actif='y' AND url=".$db->quote($url);
		if($id_commentaire!=0){ $sql .= " AND id_sous_commentaire=".$id_commentaire; }else{ $sql .= " AND id_sous_commentaire=0"; }
		$sql .= " ORDER BY id_sous_commentaire, date";
		
		foreach($db->query($sql) as $data) {
			$i++;
			mt_srand(crc32($data['email']));
			
			$commentaires .= '<div class="box-light">';
				
				if($i==1 && $id_commentaire==0)
				{
					$sql2 = "SELECT COUNT(id_commentaire) FROM p3x_commentaire WHERE actif='y' AND url=".$db->quote($url);
					$query = $db->prepare($sql2); 
					$query->execute(); 
					$row = $query->fetch();
					$count = $row[0];
					$nb = $count;
					$s='s';
					
					if($count==1){ $nb = 'Un'; }
					
					$commentaires .= '<h2>'.$nb.' commentaire'.$s.'</h2>';
				}
				
				$commentaires .= '<div class="separator"></div>
									<div class="box-light">
										<div class="letter '.$tcolor[mt_rand(0, count($tcolor) - 1)].'">'.htmlentities(substr($data['nom'], 0, 1)).'</div>
										<p class="chapeau">@'.htmlentities($data['nom']).' <span class="gray">'.$data['date'].'</span></p>
										<p>'.htmlentities($data['commentaire']).'</p>
										<form id="comform-'.$data['id_commentaire'].'" method="post" action="'.$url.'">
											<input name="action" value="poster-commentaire" type="hidden">
											<input name="email" class="hidden" type="text">
											<input name="id_sous_commentaire" value="'.$data['id_commentaire'].'" type="hidden">
											<div id="comform-div-'.$data['id_commentaire'].'" class="comform-div hidden">
												<p>Réponse à @'.htmlentities($data['nom']).'<br><textarea name="commentaire"></textarea></p>
												<p>Nom<br><input name="nom" type="text"></p>
												<p>Adresse e-mail<br><input name="emailtrue" type="text"></p>
											</div>
											<div class="clear"></div>
											<p><a class="repondre" data-rel="'.$data['id_commentaire'].'" href="#">Répondre</a></p>
											<div class="clear"></div>
										</form>
									</div>';
				
				$commentaires .= commentaires($url, $data['id_commentaire']);
				
			$commentaires .= '</div>';
		}
		
		return $commentaires;
	}

	// Insertion d'un commentaire
	
	if(isset($_POST['action']) && $_POST['action']=='poster-commentaire')
	{
		// Protection robot
		if(isset($_POST['email']) && empty($_POST['email']))
		{
			if(isset($_POST['commentaire']) && !empty($_POST['commentaire']) &&	isset($_POST['nom']) && !empty($_POST['nom']) && isset($_POST['emailtrue']) && !empty($_POST['emailtrue']))
			{
				$id_sous_commentaire = 0;
				
				if(isset($_POST['id_sous_commentaire']) && is_numeric($_POST['id_sous_commentaire'])){ $id_sous_commentaire = intval($_POST['id_sous_commentaire']); }
			
				if(filter_var($_POST['emailtrue'], FILTER_VALIDATE_EMAIL))
				{
					$sql = "INSERT INTO p3x_commentaire(
												id_sous_commentaire,
												nom,
												commentaire,
												email,
												url,
												actif,
												date
											) VALUES(
												".$id_sous_commentaire.",
												:nom,
												:commentaire,
												:emailtrue,
												:currenturl,
												'a',
												'".date("Y-m-d H:i:s")."'
											)";
					$query = $db->prepare($sql);
					$query->bindValue(':nom', $_POST['nom'], PDO::PARAM_STR);
					$query->bindValue(':commentaire', $_POST['commentaire'], PDO::PARAM_STR);
					$query->bindValue(':emailtrue', $_POST['emailtrue'], PDO::PARAM_STR);
					$query->bindValue(':currenturl', $currenturl, PDO::PARAM_STR);
					$query->execute();
					
					unset($_POST);
					
					$message_text = 'Votre message a été déposé mais vous devez attendre qu\'il soit validé.';
					$message_img = 'check';
				}
				else
				{
					$message_text = 'Votre adresse e-mail n\'est pas valide !';
				}
			}
			else
			{
				$message_text = 'Les informations obligatoires ne sont pas toutes renseignées !';
			}
		}
	}
	
	// Chargement des commentaires
	$commentaires = commentaires($currenturl, 0);
	if(!empty($commentaires)){ echo '<div class="box-light">'.$commentaires.'</div>'; }
?>
<h3>Poster un commentaire</h3>
<form method="post" action="<?php echo $currenturl; ?>">
	<input type="hidden" name="action" value="poster-commentaire" />
	<input type="text" name="email" class="hidden" />
	<p>Commentaire<br /><textarea name="commentaire"></textarea></p>
	<p>Nom<br /><input type="text" name="nom" /></p>
	<p>Adresse e-mail<br /><input type="text" name="emailtrue" /></p>
	<p><input type="submit" class="button-blue left" value="Poster mon commentaire" /></p>
	<div class="clear"></div>
	<p class="red right">Votre adresse e-mail n'est pas publiée lorsque vous ajoutez un commentaire.<br />Tous les champs sont obligatoires pour soumettre votre commentaire.</p>
	<div class="clear"></div>
</form>

Le SQL de la base de données

CREATE TABLE `p3x_commentaire` (
  `id_commentaire` smallint(4) UNSIGNED NOT NULL,
  `id_sous_commentaire` smallint(4) UNSIGNED NOT NULL,
  `nom` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `commentaire` text COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
  `url` varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  `actif` enum('y','n','a') COLLATE utf8_unicode_ci NOT NULL,
  `date` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `p3x_commentaire`
  ADD PRIMARY KEY (`id_commentaire`),
  ADD KEY `id_sous_commentaire` (`id_sous_commentaire`);

ALTER TABLE `p3x_commentaire`
  MODIFY `id_commentaire` smallint(4) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;

Un petit peu de JQuery

<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
	$('.repondre').click(function(){
		var id = $(this).attr('data-rel');
		if($('#comform-div-' + id).hasClass('hidden'))
		{
			$('.repondre').removeClass('button-blue');
			$(this).addClass('button-blue').css('float','left');
			$('.comform-div').addClass('hidden');
			$('#comform-div-' + id).find('p').show();
			$('#comform-div-' + id).removeClass('hidden');
			return false;
		}
		else
		{
			$('#comform-' + id).submit();
			return false;
		}
	});
</script>

Styles CSS

input[type=text]{padding:10px;width:280px;border:1px solid #E7E7E7;border-radius:5px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-family:Arial;}
input[type=text]:hover{background-color:#f8fbff;}
textarea{padding:10px;border:1px solid #E7E7E7;border-radius:5px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%;height:125px;}
.box-light{padding:25px;color:#333333;margin:10px 0;background:#ffffff;transition:all 0.6s ease 0s;}
	.box-light .box-light{padding:0 35px;}
		.box-light .box-light p{margin:5px 0px;}
	.box-light h2,.box-light h3,.box-light h4{margin:0;padding:0;}
	.box-light h3{margin-top:10px;}
		.box-light h3 a{text-decoration:none;}
	.box-light img{transition:all 0.6s ease 0s;display:block;}
	.box-light:hover{box-shadow:1px 1px 10px #dcdcdc;}
		.box-light .box-light:hover{box-shadow:none;}
	.box-light p{padding:0;}
.letter{background-color:#4C74AD;color:#ffffff;border-radius:50%;width:40px;height:40px;line-height:35px;font-weight:bold;text-align:center;float:left;margin-left:-35px;margin-right:15px;}
	.letter.blue{background-color:#3B689F;}
	.letter.green{background-color:#44A437;}
	.letter.orange{background-color:#ff7537;}
	.letter.purple{background-color:#b99aff;}
	.letter.gray{background-color:#888888;}
	.letter.red{background-color:#DC4739;}
.chapeau{font-size:1em;margin:5px 0;font-weight:bold;}
.gray{color:#888888;}
.red{color:#DC4739;}
.hidden{display:none;}
.clear{clear:both;}
.separator{border-top:1px solid #e7e7e7;border-bottom:1px solid #ffffff;width:100%;height:1px;margin-top:30px;margin-bottom:30px;clear:both;}
.button-blue{margin-top:10px;float:right;font-family:Arial;cursor:pointer;font-size:1em;padding:10px 15px;font-weight:bold;border-radius:5px;color:#ffffff;border:0px;background:#3e679b;box-sizing:border-box;text-align:center;}

Poster un commentaire

Commentaire

Nom

Adresse e-mail

Votre adresse e-mail n'est pas publiée lorsque vous ajoutez un commentaire.
Tous les champs sont obligatoires pour soumettre votre commentaire.