YBET

Rue Albert 1er, 7

6810 Pin - Chiny

Route Arlon - Florenville

(/fax: 061/32.00.15

Les formations sur Internet

Magasin YBET informatique   Créer son site

24. Exercice: gérer des news, communiqués de presse, ... en PHP - MySQL

1. La table MySQL des news - 2. Fichiers include - 3. Gestion des catégories - 4. Gestion des news - 5. Suppression des catégories - 6. Affichage complet - 7. Affichage par tranches - 8. Affichage par catégories - 9. Affichage par date - 10. Mise en Page

Dans cet exercice, nous allons simplement programmer un système de gestions des news (communiqués, actualités, prochaines activités, ...) à insérer sur un site existant: utilisé par exemple ici sur YBET.BE. Une page reprendra l'affichage des dernières nouvelles sous forme d'un titre, d'une description et d'une date. Nous changeons de page pour l'affichage toutes les 10 news pour ne pas surcharger l'écran.

Le développement reprend:

  1. La création de la table
  2. Le formulaire d'entrée des nouvelles
  3. Un formulaire de modification (suppression, modification, ...)
  4. La page d'affichage
  5. Un système de tri.

Pour faciliter le tri des nouvelles, nous allons utiliser également un champ catégorie qui permettra de différencier les types de nouvelles affichées: nous créerons une deuxième table reprenant les catégories et utiliserons une liste déroulante dans l'insertion ou pour le tri par catégories. Ceci permettre au final de filtrer les annonces sur une date (période) ou par types de nouvelles. Ce système pourrait également être utilisé pour créer un blog sur un site.

Toute les fichiers PHP reprenant la partie gestion sera insérée dans un sous dossier admin à protéger. Rien de bien difficile puisque la majorité de ces fonctionnalités a déjà été vu dans les chapitres précédents.

1.Les tables MySQL des news.

La table news va reprendre les champs suivants:

Nom Type Remarque requête associée
uid smallint(6) auto-increment, clé primaire uid smallint(6) primary key NOT NULL auto_increment
titre varchar(100) titre de votre nouvelle titre varchar(100) Not Null
news TEXT texte limité à 65535 caractères news blob Not Null
datenews date date du jour, serveur datenews date
categorie varchar(30) categorie varchar (30) Not Null

La table categorie_news est on ne peut plus simple:

Nom Type Remarque Requête associée
categorie Varchar(30)   categorie varchar(30) primary key not null

La création automatique des tables ne va pas poser trop de problèmes. fichier news-table.php

<?php
/* remplacez dans les lignes ci-dessus:
localhost par le nom du serveur (fourni par l'hébergeur)
root par le nom utilisateur de la base de donnée (fourni par l'hébergeur)
password par le mot de passe (fourni par l'hébergeur)
ybet par le nom de la base de données (fourni par l'hébergeur)
*/
if(!mysql_connect('localhost','root','password')){
Echo'Connection Impossible';
exit();
}
Mysql_select_db('ybet');

// création des tables
$requete="CREATE TABLE if not exists news (uid smallint(6) primary key NOT NULL auto_increment,titre varchar(100) Not null,news TEXT not null, datenews date, categorie varchar(30))";
$resultat=mysql_query($requete);
$erreur=mysql_error();
print($erreur);
$requete="CREATE TABLE if not exists categorie_news (categorie varchar(30) primary key)";
$resultat=mysql_query($requete);
$erreur=mysql_error();
print($erreur);
mysql_close()

2. Fichiers includes.

Comme dans les précédents développements, nous utilisons 2 fichiers inclus dans un sous- dossier includes: start.php et stop.php.

start.php

<?php
/* remplacez dans les lignes ci-dessus:
localhost par le nom du serveur (fourni par l'hébergeur)
root par le nom utilisateur de la base de donnée (fourni par l'hébergeur)
password par le mot de passe (fourni par l'hébergeur)
ybet par le nom de la base de données (fourni par l'hébergeur)
*/
if(!mysql_connect('localhost','root','password')){
Echo'Connection Impossible';
exit();
}
Mysql_select_db('ybet');

?>

stop.php

mysql_close();

3. Gestion les catégories

La première partie va nous permettre de gérer les catégories, nous allons faire le plus simple possible.

3.1. Affichage des catégories.

C'est une simple requête de sélection, sans filtre, juste classée par ordre alphabétique sur le nom de la catégorie.

news-affichage-cat.php

<?php
require('../include/start.php');
$requete="select * from categorie_news order by categorie asc";
$resultat=mysql_query($requete);
$valeur=mysql_query($requete);
$tableau=array();
if (mysql_num_rows($valeur)<>0)
{
while ($tableau=mysql_fetch_array($valeur)){
echo stripslashes($tableau['categorie'])."<br>";
}
}
?>

3.2. Insertion catégorie

Nous allons simplement créer un petit formulaire d'entrée. Comme le champ categorie est de type primary key, rentrer 2 fois le même mot est impossible (sauf majuscules / minuscules). De toute façon, nous affichons les catégories déjà créée au dessus.

Pour éviter 2 fichiers, nous allons le faire en auto-invocant, en utilisant la méthode POST.

news-insertion-cat.php

<?php
require('..\include\start.php');
if (isset($_POST['B1'])){
$categorie=addslashes($_POST['categorie']);
$requete="insert categorie_news set categorie='$categorie'";
$resultat=mysql_query($requete);
}
require('news-affichage-cat.php');
$form="<form method=\"POST\">
<p><input type=\"text\" name=\"categorie\" size=\"30\"></p>
<p><input type=\"submit\" value=\"Insérer\" name=\"B1\"></p>
</form>";
echo$form;
?>

Remarque, en insérant l'affichage après le test, la nouvelle catégorie est également affichée.

3.3. Suppression de catégorie.

Pour pouvoir supprimer une catégorie, nous devons obligatoirement vérifier si aucune news n'utilise cette catégorie. Cette partie sera fait après l'insertion des news.

4. Gestion des news.

Pour pouvoir gérer les news, nous devons d'abord les afficher. Pourtant, dans la partie administration, nous allons les afficher simplement en liste, en tronquant le contenu en lui-même.

4.1. Affichage simple en liste

Dans cette partie, nous allons simplement afficher les news les unes à la suite de l'autre, sans trop s'occuper de la mise en page. Nous n'affichons également que les 20 premiers caractères de la description de la nouvelle.

<?php
require('.../include/start.php');
$requete="select * from news order by uid asc";
$resultat= mysql_query($requete);
$tableau=array();
while ($tableau=mysql_fetch_array($resultat)){
echo $tableau['uid'].": ".stripslashes($tableau['titre'])." ".stripslashes(substr($tableau['news'],0,40))."... ".$tableau['datenews']."-".$tableau['categorie']."<br>";
}
?>

4.2. Insertion de la news.

De nouveau, nous allons utiliser un formulaire auto-invocant: peu de difficulté, sauf récupérer les catégories de la table catégorie dans une table déroulante.

Le fichier news-insertion.php

<?php
require('..\include\start.php');
// récupération des catégories
$requete="select * from categorie_news order by categorie asc";
$resultat=mysql_query($requete);
$valeur=mysql_query($requete);
$tableau=array();
$cat=array();
$i=0;
if (mysql_num_rows($valeur)<>0)
{
while ($tableau=mysql_fetch_array($valeur)){
$cat[$i]=$tableau['categorie']."<br>";
$i=$i=1;
}
}
$nb_cat=count($cat);
//echo $nb_cat;
$i=0;
if (isset($_POST['B1'])){
$titre=addslashes($_POST['titre']);
$news=nl2br(addslashes($_POST['news']));
$categorie=addslashes($_POST['categorie']);
$datenews=date('Ymd');
if ($titre<>"" and $news<>"")
{
$requete="insert news set titre='$titre',news='$news',categorie='$categorie',datenews='$datenews'";
$entrees=mysql_query($requete);
echo"Votre news a bien été enregistrée";
die('<meta http-equiv="refresh" content="3; URL=news-insertion.php">');
}
}
require('news-affichage.php');
$form="<form method=\"POST\">
<p>Titre: <input type=\"text\" name=\"titre\" size=\"100\"></p>
<p>Le contenu: <textarea rows=\"2\" name=\"news\" cols=\"50\"></textarea></p>
<p><select size=\"1\" name=\"categorie\">";
while($i<$nb_cat)
{
$form=$form."<option>".$cat[$i]."</option>";
$i=$i+1;
}
$form=$form."</select></p><p><input type=\"submit\" value=\"Envoyer\" name=\"B1\"></p>
</form>";
echo$form;
?>

La fonction DIE renvoie automatiquement vers une nouvelle insertion et permet de ne pas insérer plusieurs fois la même annonce automatiquement.

4.3. Suppression d'une news.

Nous allons simplement afficher les news et demander via un formulaire le numéro de la news (uid) à effacer.

<?php

if (isset($_POST['go']))
{
$uid=$_POST['numero'];
require('../includes/start.php');
$requete="DELETE From news where uid='$uid'";
$valeur=mysql_query($requete);
mysql_close();
}

require('news-affichage.php');
$form="<form method=\"POST\">
<p>Numéro de la news: <input type=\"text\" name=\"numero\" size=\"20\"></p>
<p><input type=\"submit\" value=\"Envoyer\" name=\"go\"></p>
</form>";
echo$form;
?>

4.4. Modification d'une news.

La procédure est équivalente à celle d'effacement, sauf qu'une fois la nouvelle sélectionnée, nous devons récupérer les données dans un formulaire pour pouvoir la modifiée. Nous utilisons 2 fichiers distincts. Le premier news-modification.php affiche les nouvelles et permet de sélectionner l'annonce à modifier. Le deuxième: news-modification1.php permet la modification en elle-même de la news. Les 2 fichiers utilisent un formulaire en méthode POST.

news-modification.php

<?php
require('news-affichage.php');
?>
<form name='modification' action='news-modification1.php' method='post'>
<input name='numero' type='text' size='20'><br>
<input name='go' type='submit' value='modifier'><br>
</form>

news-modification1.php

<?php
if (isset($_POST['go']))
{
$uid=$_POST['numero'];
include('../includes/start.php');
$requete="select * from news where uid='$uid'";
$resultat=mysql_query($requete);
// récupération des anciennes valeurs
while ($tableau=mysql_fetch_array($resultat))
{
$titre=stripslashes($tableau['titre']);
echo$titre;
$news=stripslashes($tableau['news']);
$categorie=stripslashes($tableau['categorie']);
echo$categorie;
//
}
// récupération des catégories
$requete="select * from categorie_news order by categorie asc";
$resultat=mysql_query($requete);
$valeur=mysql_query($requete);
$tableau=array();
$cat=array();
$i=0;
if (mysql_num_rows($valeur)<>0)
{
while ($tableau=mysql_fetch_array($valeur)){
$cat[$i]=$tableau['categorie']."<br>";
$i=$i=1;
}
$nb_cat=count($cat);
//echo $nb_cat;
}
}
if (isset($_POST['B1']))
{
$titre1=addslashes($_POST['titre']);
$news1=nl2br(addslashes($_POST['news']));
$categorie1=addslashes($_POST['categorie']);
$uid=$_POST['uid'];
if ($titre1<>"" and $news1<>"")
{
require('../includes/start.php');
$requete="update news set titre='$titre1',news='$news1',categorie='$categorie1' where uid='$uid'";
$valeur=mysql_query($requete);
echo"News modifée";
die('<meta http-equiv="refresh" content="3; URL=news-modification.php">');

}else{
echo"vous ne pouvez pas rentrer de valeurs nulles";
die('<meta http-equiv="refresh" content="3; URL=news-modification.php">');
}
}
$i=0;
$form="<form method=\"POST\">
<p>Titre: <input type=\"text\" name=\"titre\" size=\"100\" value=\"".$titre."\"></p>
<p>Le contenu: <textarea name=\"news\" rows=\"2\" cols=\"50\">".$news."</textarea></p>
<input type=\"hidden\" name=\"uid\" value=\"".$uid."\">
<p><select size=\"1\" name=\"categorie\">
<p><option selected>".$categorie;
while($i<$nb_cat)
{
$form=$form."<option>".$cat[$i]."</option>";
$i=$i+1;
}
$form=$form."</select></p><p><input type=\"submit\" value=\"Envoyer\" name=\"B1\"></p>
</form>";
echo$form;
?>

5. Suppression des catégories.

Cette partie n'a rien de bien compliqué, nous devons juste vérifié si aucune news ne reprend comme catégorie celle que nous souhaitons supprimer.

<?php
require('..\includes\start.php');
if (isset($_POST['B1'])){
$categorie=addslashes($_POST['categorie']);
// vérification dans la table news si cette catégorie est inutilisée
$requete="select * from news where categorie='$categorie'";
$valeur=mysql_query($requete);
$i=mysql_num_rows($valeur);
if ($i<>0)
{
// catégorie utilisée
echo"<b>Cette catégorie est utilisée dans les news et ne peut être effacée</b>";
die('<meta http-equiv="refresh" content="3; URL=news-supprimer-cat.php">');

}else{
$requete="delete from categorie_news where categorie='$categorie'";
$resultat=mysql_query($requete);
echo "<b>".mysql_affected_rows()." catégorie supprimée</b>";
die('<meta http-equiv="refresh" content="3; URL=news-supprimer-cat.php">');
}
}
require('news-affichage-cat.php');
$form="<form method=\"POST\">
<p><input type=\"text\" name=\"categorie\" size=\"30\"></p>
<p><input type=\"submit\" value=\"Supprimer\" name=\"B1\"></p>
</form>";
echo$form;
?>

6. Affichage complet des news

Nous allons simplement mettre en page les nouvelles insérées dans la table. Remarquez que dans l'insertion des news, nous n'avons strictement fait aucune modification des données entrées (à part ajouter les caractères de contrôle spécifiques au php). Vous pouvez donc insérer du code HTLM dans les news sans problèmes (lien, images, ...).

L'affichage va simplement reprendre dans un tableau la liste classée par date d'insertion descendante, de la dernière à la première). Commençons par créer l'affichage des nouvelles. Dans cette partie, nous ne découpons pas les résultats, elles seront toutes affichées.

<?php
// affichages des nouvelles sans découpage.
require('includes/start.php');
$requete="select * from news order by datenews desc";
$resultat=mysql_query($requete);
while ($tableau=mysql_fetch_array($resultat)){
echo "<h2><font color=\"#0000FF\">".stripslashes($tableau['titre'])."</font></h2>";
echo"<p>".stripslashes($tableau['news'])."</p>";
echo"<p>".$tableau['datenews']." - ".$tableau['categorie']."</p>";
echo"<hr>";
}
?>

Ce développement ne fait que d'afficher toutes les nouvelles les unes à la suite de l'autre. Seule une petite mise en page est utilisée (titre 1 en gras et en bleu pour le titre). Il est nettement perfectible. La première chose est de limiter l'affichage à 10 news (ou un nombre à déterminer). La deuxième partie va utiliser une feuille de style, plus facile à modifier pour un débutant.

7. Affichage par tranches

L'affichage est finalement identique à ci-dessus. Nous allons juste utiliser l'option LIMIT dans la requête de sélection. Ceci va également créer différentes pages avec un paramètre dans l'URL en remplaçant par les lignes ci-dessus, nous n'affichons que les 10 premières lignes de news:

$i=0;
$l=10;
$requete="select * from news order by datenews desc limit $i,$l";

La première difficulté est de déterminer le nombre de pages totales de news. Nous allons créer 2 requêtes sur la table. La première va simplement déterminer le nombre de lignes de résultats et permettre de créer les différentes pages. La deuxième va afficher les résultats par tranches de 10 nouvelles. Le passage du numéro de page se fait à l'aide de la méthode GET. L'URL sera de type news-affichage.php?page=1, ...

Le fichier news-affichage.php

<?php
// affichages des nouvelles sans découpage.
require('includes/start.php');
if (!isset($_GET['page']))
{
$i=0;
$l=10;
}else{
$i=10*$_GET['page'];
$l=10;
}
$requete="select * from news order by datenews";
$resultat=mysql_query($requete);
$r=mysql_num_rows($resultat);
$t=round($r/10)+1;
// fin de récupération du nombre de résultat: $r est le nombre de nouvelles, $t le nombre de pages.
$requete="select * from news order by datenews desc limit $i,$l";
$resultat=mysql_query($requete);
while ($tableau=mysql_fetch_array($resultat)){
echo "<h2><font color=\"#0000FF\">".stripslashes($tableau['titre'])."</font></h2>";
echo"<p>".stripslashes($tableau['news'])."</p>";
echo"<p>".$tableau['datenews']." - ".$tableau['categorie']."</p>";
echo"<hr>";
}
$j=1;
echo"<a href=\"news-affichage-lim.php\">Dernières news</a>";
while ($j<$t)
{
echo" - <a href=\"news-affichage-lim.php?page=".$j."\">page".$j."</a></p>";
$j=$j+1;
}
?>

Les liens pour passer d'une page à l'autre sont insérés en-dessous. Remarquez que la page d'entrées (les 10 dernières news) n'utilise pas de paramètres, même si l'adresse news-affichage.php?page=0 fonctionne (ceci évite le duplicate content pour les moteurs de recherche, néfaste au référencement des pages).

8. Affichage par catégories

Nous allons permettre l'affichage des news suivant certains filtres, par exemple par date, par catégories, ... Nous développerons également un petit moteur de recherche dans la partie suivante.

Relativement simple, cette partie va juste demander la catégorie dans un petit formulaire, faire passer le paramètre par la méthode GET et le transmettre au fichier  news-cat.php.

Le formulaire à insérer dans vos pages (il est repris dans le fichier news-form-cat.php):

<?php
// récupération des catégories
require('includes/start.php');
$requete="select * from categorie_news order by categorie asc";
$resultat=mysql_query($requete);
$valeur=mysql_query($requete);
$tableau=array();
$cat=array();
$i=0;
if (mysql_num_rows($valeur)<>0)
{
while ($tableau=mysql_fetch_array($valeur)){
$cat[$i]=$tableau['categorie']."<br>";
$i=$i+1;
}
$nb_cat=count($cat);
$i=0;
$form="<form method=\"GET\" action=\"news-categorie.php\">
<p><select size=\"1\" name=\"categorie\">";
while($i<$nb_cat)
{
$form=$form."<option>".$cat[$i]."</option>";
$i=$i+1;
}
$form=$form."</select></p><p><input type=\"submit\" value=\"Envoyer\"></p>
</form>";
echo$form;
}
?>

Le fichier news-categorie.php


<?php
// affichages des nouvelles par catégorie
require('includes/start.php');
if (!isset($_GET['categorie']))
{
//pas de catégories sélectionnées
die('<meta http-equiv="refresh" content="0; URL=news-affichage.php">');
}else{
$categorie=$_GET['categorie'];
echo$categorie;
$requete="select * from news where categorie='$categorie'";
$resultat=mysql_query($requete);
$r=mysql_num_rows($resultat);
$t=round(($r-1)/10,0);
echo$t."<br>";
// fin de récupération du nombre de résultat: $r est le nombre de nouvelles, $t le nombre de pages.
if (!isset($_GET['page']))
{
$i=0;
$l=10;
}else{
$i=10*$_GET['page'];
$l=10;
}
$requete="select * from news where categorie='$categorie' order by datenews desc limit $i,$l";
$resultat=mysql_query($requete);
}

while ($tableau=mysql_fetch_array($resultat)){
echo "<h2><font color=\"#0000FF\">".stripslashes($tableau['titre'])."</font></h2>";
echo"<p>".stripslashes($tableau['news'])."</p>";
echo"<p>".$tableau['datenews']." - ".$tableau['categorie']."</p>";
echo"<hr>";
}
// affichage des liens
$j=0;
?>
<p>
<?php
while ($j<$t)
{
echo" <a href=\"news-categorie.php?page=".$j."&categorie=".$categorie."\">".$categorie."-".$j."</a>";
$j=$j+1;
}
?>
</p>

Le procédé est identique à celui-ci dessus pour les news complète. Si une catégorie n'est pas sélectionnée, cette page reprend automatiquement la page standard news-affichage.php.

9. Affichage par date.

Cette partie va permettre à un utilisateur de sélectionner les news dans une période donnée (de date à date). Le premier développement va être le formulaire permettant de sélectionner les dates. Nous devons également vérifier si les dates sont valides. Nous n'utilisons pas ici de script purs, juste des fonctions en PHP. C'est là le problème.

Deux problèmes à régler:

La première est la plus difficile. Elle va utiliser la fonction checkdate ( int mois, int jour, int année ) où: mois égale de 1 à 12, jour de 1 à 31 et année de 1 à 32767. La fonction tient compte des années bissextiles. Le formulaire doit donc être auto-invocant avant d'envoyer le formulaire suivant la méthode GET.

Le fichier de rentrée des dates et de vérification des données est repris sous news-form-date.php.

<?php
if (isset($_POST['B1']))
{
$date_init=$_POST['date_init'];
$date_fin=$_POST['date_fin'];
// vérification de la date initiale
$day_init=substr($date_init,0,2);
$mois_init=substr($date_init,3,2);
$annee_init=substr($date_init,6,4);
$day_fin=substr($date_fin,0,2);
$mois_fin=substr($date_fin,3,2);
$annee_fin=substr($date_fin,6,4);
// vérification de la date la plus ancienne. Version PHP<5.0, erreur en cas de date indérieure au 01/01/1970
if ($annee_init < 1970){
$annee_init=1970;
}
if ($annee_fin < 1970){
$annee_fin=1970;
}
if((!is_numeric($day_init))|| (!is_numeric($mois_init)) || (!is_numeric($annee_init))||(!checkdate($mois_init,$day_init,$annee_init)))
{
echo"Date initiale non valide";
$date_init=date('d/m/Y');
}elseif ((!is_numeric($day_fin))|| (!is_numeric($mois_fin)) || (!is_numeric($annee_fin))||(!checkdate($mois_fin,$day_fin,$annee_fin))){
echo"Date finale non valide";
$date_fin=date('d/m/Y');
}else{
// vérification date la plus ancienne
if (mktime(0,0,0,$mois_init,$day_init,$annee_init)> mktime(0,0,0,$mois_fin,$day_fin,$annee_fin)){
$day1=($annee_fin.$mois_fin.$day_fin);
$day2=($annee_init.$mois_init.$day_init);
}else{
$day2=($annee_fin.$mois_fin.$day_fin);
$day1=($annee_init.$mois_init.$day_init);
}
//requête de sélection
require ('includes\start.php');
$requete="select * from news where (datenews>='$day1') and (datenews<='$day2')";
$resultat=mysql_query($requete);
while ($tableau=mysql_fetch_array($resultat)){
echo "<h2><font color=\"#0000FF\">".stripslashes($tableau['titre'])."</font></h2>";
echo"<p>".stripslashes($tableau['news'])."</p>";
echo"<p>".$tableau['datenews']." - ".$tableau['categorie']."</p>";
echo"<hr>";
}
}
}else{
$date_init=date('d/m/Y');
$date_fin=date('d/m/Y');
}
// formulaire

$form="<form method=\"POST\"><p>Date de départ: <input type=\"text\" name=\"date_init\" size=\"10\" value=\"".$date_init."\"></p>
<p>Date finale: <input type=\"text\" name=\"date_fin\" size=\"10\" value=\"".$date_fin."\"></p>
<p><input type=\"submit\" value=\"Sélectionner\" name=\"B1\"></p>
</form>";
echo$form;
?>

Remarque: l'affichage est complet, il n'y a pas de pages séparées toutes les 10 news.

10. Mise en forme

Il ne nous reste plus qu'à mettre en forme nos différents fichiers pour la présentation. Nous utiliserons simplement un tableau comme ci-dessus. Les différentes parties sont reprises dans le dossier includes sous les noms header.php, footer.php, column_right.php (colonne de droite) et column_left.php (colonne de gauche)

Header
column_left Corps de la page (contenu) column_right
Footer

Dans le pack d'installation, les colonnes de gauche et de droites sont déjà remplies. Il vous suffit de modifier le header (en-tête) et le footer (pied de page) selon le design de votre site. Différentes parties de navigation peuvent également être insérées dans vos différentes pages.

Ce développement est téléchargeable sur le site dahut.be.

> 25. Utilisation des cookies
<22 . Suivi des utilisateurs

Mise en ligne: 30/11/2006