Système de news en PHP avec flux RSS

Après une absence prolongée sur le blog (bac blanc) je reviens avec un tutoriel vidéo qui risque d’en intéresser plus d’un. Nous allons voir comment faire un système de news avec un flux RSS, le tout administrable depuis une page protégée par htaccess.

La vidéo est longue (1h20 min) car j’ai essayé d’être le plus précis possible pour vous proposer un système relativement complet. Avant de commencer, une petite description de ce que l’on va faire s’impose :
Le système pour afficher les news est découpée en 2 parties, une partie ou l’on affiche les descriptions des 5 dernières news (sur la page d’accueil du site par exemple) et une partie ou l’on affiche la news complète.
La page d’administration est elle aussi découpé en plusieurs parties. Pour résumé, on peut créer une news avec un système utilisant tinymce pour pouvoir mettre en page le texte correctement et une partie pour modifier et/ou supprimer les news déjà faites.
Et enfin, pour rester original et ne pas faire comme dans la plupart des tutoriels sur internet qui s’arrête ici, je vous montre comment faire un flux RSS pour proposer à vos visiteurs de s’abonner et pour optimiser le référencement de vos pages.

Bon, j’ai pas mal de trucs à préciser. Premièrement, et c’est quelque chose que j’ai longtemps cherché mais je n’en ai pas parlé dans le tutoriel, c’est qu’on pourrait ajouter un système de pagination. Surtout sur les pages d’administration, vous imaginez avoir 50 news d’un coup ?? J’ai vraiment beaucoup cherché et j’ai trouvé un système qui est très sympa, fait par un autre blogueur. Je l’utilise sur mon deuxième site, il est facile à mettre en place et je n’ai jamais eu de problème. Je précise que c’est un système de pagination complète du genre « 1 2 3 … 40 41 », pas comme ceux qu’on a l’habitude de voir qui ne sont pas top. Pour le script, alors voir l’article sur son blog.

Ensuite, second point : tinyMce. J’en parle énormément dans la vidéo, j’ai expliqué un peu son fonctionnement sans trop détailler parce que j’ai déjà fait un tutoriel. Je vous conseille d’aller le lire, c’est toujours un plus. Dans le même contexte, j’ai parlé d’une faille de sécurité (c’est expliqué dans le tutoriel sur tinymce) mais je vais en reparler un petit peu.
Pour faire simple, j’ai dit que tinyMCE nous protège des pirates qui essayeraient de mettre du code HTML directement. Or tinyMCE est en javascript, donc si le pirate désactive le javascript de son navigateur, tinyMCE n’apparait pas et donc ne protège pas le textarea. Dans notre cas, ce n’est pas spécialement grave puisque la page d’administration est protégée par htaccess et que normalement on est les seuls à y avoir accès. Une méthode pour parer à ça, c’est de faire le textarea en javascript, mais j’ai constaté que cela pose des problèmes dans le cas ou on modifie les news (je n’entre pas dans les détails …).

Dans la vidéo, j’ai parlé des htaccess et htpasswd qui protège le dossier admin par mot de passe. C’est essentiel, en effet quelqu’un qui aurait accès à la page d’administration pourrait supprimer/modifier toutes les news ! Je n’ai pas été très précis dans la vidéo, c’est pour cela que je vous recommande vivement de lire le tutoriel déjà présent sur le site du zéro.
Un autre petit détail, c’est que pour la première fois, j’ai choisie l’option « CURRENT_TIMESTAMP » dans la base de données. Je le précise pour ceux qui copie simplement les codes sans regarder la vidéo. Avec cette option, automatiquement la date se remplie à chaque nouvelle entrée sans qu’on ait besoin de le faire en php. C’est aussi pour cela que j’utilise la fonction « strtotime » qui permet de convertir une date en timestamp.

Bon je crois que je n’ai rien oublié, dans le cas contraire dites le. Voici les codes, je les ai commentés pour que vous puissiez comprendre. C’est long, mais ce n’est pas très compliqué, beaucoup de choses se répètent (notamment les requêtes). Rien ne vous empêche de les modifier, au contraire. Ce que je propose, c’est le fruit de mon raisonnement et je ne suis pas un pro en php. Donc si vous utilisez ces codes, faites quand même attention. (d’ailleurs si quelqu’un à un commentaire à faire dessus, je serai ravi de l’écouter).

1.Le ficher config.php qui contient toutes les variables pour se connecter à la BDD. C’est pratique, si un jour vous changez d’hébergeur, vous n’aurez que ce fichier à modifier.

<?php
/*
Identifiants pour se connecter à la BDD
*/
	$adresse = 'localhost'; 
	$nom = 'root';
	$motdepasse = '';
	$database = 'tutoriel';

?>

2. Le code de la page index qui permet d’afficher les news (j’ai aussi mis la ligne de code pour « déclarer » notre flux rss et avoir le logo dans la barre d’adresse).

<!-- Entre les balises head -->
       <link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="http://www.votresite.com/dossier/news/flux.php" />
<!-- ############# -->

	<h1>Les dernières news !</h1>
<?php
	
/*
Connexion à la BDD
*/
require "config.php";
mysql_connect($adresse, $nom, $motdepasse);
mysql_select_db($database);

/*
Affichage d'une news en particulier
*/
if(isset($_GET['id'])){
	
	$id = intval(htmlentities($_GET['id']));
	/*
	Si l'id !=0, intval renvoie quelque chose de bon
	*/
	if($id != 0){
		
		$sql = 'SELECT * FROM news WHERE id='.$id.'';
		$req = mysql_query($sql) or die(mysql_error());
		$data = mysql_fetch_assoc($req);
			
		echo '<h1>'.stripslashes($data['titre']).'</h1>';
		echo '<em>'. date("d/m/Y G:i", strtotime($data['date'])).'</em>';
		echo '<p>'.stripslashes($data['contenu']).'</p>';

			
			
	}
	/*
	id ==0, intval renvoie certainement qqch de faux
	*/
	else
	{
		echo "Erreur";
	}
	
}
/*
Listage des 5 dernières news
*/
else
{
	
	$sql = 'SELECT * FROM news LIMIT 0,4';
	$req = mysql_query($sql) or die(mysql_error());
	while($data = mysql_fetch_assoc($req)){
		?>
		<h2><a href="index.php?id=<?php echo $data['id']; ?>"><?php echo stripslashes($data['titre']);?></a></h2>
		<em><?php echo date("d/m/Y G:i", strtotime($data['date'])); ?></em>
		<p><?php echo stripslashes($data['description']); ?></p>
		
		<?php
		
	}
	}
	
	
	?>

3.Tout le code php de la page d’administration (le reste étant pour le design). J’ai essayé de commenter au maximum le code sans trop en mettre, j’espère que ça ira :

<h1 style="text-align:center;">Page d'administration</h1>
<?php
/*
Connexion à la BDD
*/
require "../config.php";
mysql_connect($adresse, $nom, $motdepasse);
mysql_select_db($database);

/*
Si une action est posté par l'url, on veut faire qqch, on fait un switch pour prévoir tout les cas :
*/
if(isset($_GET['action']))
{
	$action = addslashes(htmlentities($_GET['action']));
		
		
	switch ($action){
		
	/*
	Action = creer, on veut faire une nouvelle news
	*/
	case "creer":
	/*
	Si les variables sont déja posté, on les stockes dans la BDD 
	*/
	if(isset($_POST['titre']) AND isset($_POST['description']) AND isset($_POST['contenu'])){
	
	extract($_POST);
	$titre = addslashes(htmlentities($titre));
	$description = addslashes($description);
	$contenu = addslashes($contenu);
	
	$sql = 'INSERT INTO news(titre, description, contenu) VALUES ("'.$titre.'", "'.$description.'", "'.$contenu.'")';
	$req = mysql_query($sql) or die(mysql_error());
	echo "<a href=\"admin.php\">Cliquez ici</a>";
		
	}
	/*
	Les variables ne sont pas posté, on affiche le formulaire pour créer la news
	*/
	else
	{
		
	?>
	<form method="post" action="admin.php?action=creer">
	
	Titre : <br/><input type="text" name="titre" /><br/>
	Description :<br/><textarea name="description" class="mceEditor"></textarea><br/>
	Contenu :<br/><textarea name="contenu" class="mceEditor"></textarea><br/>
	<input type="submit" value="envoyer"/>
	</form>
		
	<?php
	}
	break; // creer
		
	/*
	Action = Gerer, on veut lister les news dans le but de les modifier/supprimer
	*/
	case "gerer":
	$sql = 'SELECT * FROM news';
	$req = mysql_query($sql) or die(mysql_error());
		
	echo "<ul>";
	while($data = mysql_fetch_assoc($req)){
			
		echo '<li>'.$data['titre'].' -- <a href="admin.php?action=modifier&amp;id='.$data['id'].'">Modifier</a> -- <a href="admin.php?action=supprimer&amp;id='.$data['id'].'">X</a></li>';
		
	}
	echo "</ul>";
	break;
		
	/*
	Action = Modifier, on veut modifier une news
	*/
	case "modifier":
		
	/*
	Si l'id existe, tout se passe bien :
	*/
	if(isset($_GET['id']))
	{
	$id = intval(htmlentities($_GET['id']));
		
		/*
		Si des données POST sont déja envoyer, il faut les stocké dans la BDD
		*/
		if(isset($_POST['titre']) AND isset($_POST['description']) AND isset($_POST['contenu'])){
		
			extract($_POST);
			$titre = addslashes(htmlentities($titre));
			$description = addslashes($description);
			$contenu = addslashes($contenu);
				
			$sql = 'UPDATE news SET titre="'.$titre.'", description="'.$description.'", contenu="'.$contenu.'" WHERE id='.$id.'';
			$req = mysql_query($sql) or die(mysql_error());
				
			echo 'Ok, <a href="admin.php">cliquez ici</a> pour revenir';
				
			}
				
		/*
		Les données POST n'existe pas, on recupère les données de la news pour les réafficher dans le formulaire
		*/
		else
		{

					
			$sql = 'SELECT * FROM news WHERE id='.$id.'';
			$req = mysql_query($sql) or die(mysql_error());
			$data = mysql_fetch_assoc($req);
					
			?>
			<form method="post" action="admin.php?action=modifier&amp;id=<?php echo $data['id'];?>">
					
			Titre : <br/><input type="text" name="titre" value="<?php echo $data['titre'];?>"/><br/>
			Description :<br/><textarea name="description" class="mceEditor"><?php echo $data['description'];?></textarea><br/>
			Contenu :<br/><textarea name="contenu" class="mceEditor"><?php echo $data['contenu'];?></textarea><br/>
			<input type="submit" value="envoyer"/>
			</form>
					
			<?php
			
		}
	}
		
	/*
	Si l'id n'existe pas, on a un problème, on peut rien faire
	*/
	else
	{
	echo "Erreur";
	}
	break; // fin cas modifier
		
		
	/*
	Action = supprimer, on supprime une news
	*/
	case "supprimer":
	
	/*
	Si l'i existe, on fait une simple requète pour supprimer la news
	*/
	if(isset($_GET['id']))
	{
	$id = intval(htmlentities($_GET['id']));
		
	$sql ='DELETE FROM news WHERE id='.$id.'';
		
	$req= mysql_query($sql) or die(mysql_error());
	echo '<a href="admin.php">Cliquez ici</a>';
		
	}
	/*
	Pas d'id ? Probleme
	*/
	else
	{
	echo "erreur";
	}
	break;
		
	}

}
/*
Dans le cas ou il n'y a pas d'action posté dans l'url, on affiche nos choix via une liste
*/
else
{
	?>
	<ul>
	<li><a href="admin.php?action=creer">Créer une news</a></li>
	<li><a href="admin.php?action=gerer">Gérer</a></li>
	</ul>
	<?
}
	
?>

4.Pour terminer, le code du fichier qui génère le flux RSS. Je me suis cantonné au minimum, mais en faisant quelques recherches vous verrez que vous pourrez ajouter des informations supplémentaires facilement (en ajoutant un élément dans la boucle en fait).

<?php
/*
Connexion à la BDD
*/
require "config.php";
mysql_connect($adresse, $nom, $motdepasse);
mysql_select_db($database);
mysql_query("SETNAMES 'utf8'");

/*
On est olbigé d'écire ça avec un "echo" a cause du "<? et ?>" qui ressemble au php
*/
echo '<?xml version="1.0" encoding="iso-8859-1"?>';

/*
Liste des dernières 10 news
*/
$sql = 'SELECT * FROM news LIMIT 0,9';
$req = mysql_query($sql) or die(mysql_error());

?>
<rss version="2.0">
    <channel>
        <title>Tutoriels-video</title>
        <description>Flux tuto video</description>
        <link>https://www.tutoriels-video.fr</link>
        
<?php

/*
On boucle le motif qui se répètera
*/
while ($data = mysql_fetch_assoc($req))
{

?>
	<item>
            <title><?php echo stripslashes($data['titre']);?></title>
	    <!-- On utilise "<![CDATA[ truc à afficher ]]>" car il y a du code html, c'est pour éviter les bugs -->
            <description><![CDATA[<?php echo stripslashes($data['description']);?>]]></description>
            <pubDate> <?php echo ''.date("D, d M Y G:i:s", strtotime($data['date'])).' GMT'; ?> </pubDate>
            <link>http://127.0.0.1/tutoriel/news/index.php?id=<?php echo $data['id'];?></link>
        </item>
	
<?php
}
?>
    </channel>
</rss>

Étant donné que ces codes sont long, je vous ai fait un petit fichier .zip (ou .tar.gz pour ceux qui veulent ce format) avec tous les fichiers du tutoriel. J’ai même, améliorer (légèrement) la mise en page.


Télécharger l’archive en .zip
Télécharger l’archive en .tar.gz (linux)

Le tutoriel est enfin terminé, j’espère que cela vous aura plu, si vous avez des questions laissez des commentaires ou faites un tour sur le forum qui est plus adapté pour poster du code !