juin 27
12

Créer un site d`entreprise de A à  Z 3/3 : L’administration en PHP/MySQL

Créer un site d`entreprise de A à  Z 3/3 : L’administration en PHP/MySQL

Langage : PHP & MySQL

Difficulté : Débutant

Temps estimé : 4 heures

Télécharger les fichiers sources
Vous devez être logués ou enregistrés pour télécharger !

Design Spartan (Gaétan Weltzer) clôt ce tutoriel de création de site par le développement de l’administration en PHP/MySQL.

L’objectif de ce tutoriel assez long est d’offrir un cas pratique avec une réflexion derrière. En situation réelle pour une entreprise, comment se passe la réalisation d’un site Internet de présentation ? Par où commence-t-on et comment finit-on, voici ce que nous allons voir ensemble. Mais tout d’abord, voici les captures d’écran de l’administration terminée et dynamique de cette troisième partie :

interface d'administration Real tea

interface d'administration Real tea
interface d'administration Real tea

Captures d’écran de l’administration fonctionnelle de Real Tea


A lire avant de commencer

Plutôt que de faire un simple tutoriel de webdesign, je souhaite vous emmener dans la création d’un site Internet pour une entreprise fictive de A à  Z : de la phase de réflexion jusqu’à  la mise en ligne du site en passant par le webdesign, l’intégration et le développement. Néanmoins pour ce long exercice, nous ne nous pencherons dans la phase de réalisation que sur la page d’accueil étant donné que les autres pages sont simplement déclinées de celle-ci. Ainsi je parlerais des autres pages sans voir en détail le webdesign ou l’intégration.

Pour cet exercice, je vais vous montrer le procédé de création d’un site-vitrine qui est à  peu près le même pour la majorité des entreprises souhaitant présenter leur activité et entrer en contact avec de potentiels clients. Pour tout de même partir dans l’originalité et montrer comment on peut s’adapter au cas par cas (notamment en matière de webdesign), j’ai décidé de réaliser le site d’une entreprise de vente de thé de qualité qui possède plusieurs boutiques en France. Le but de ce tutoriel est de partir de cet exemple précis (que vous ne rencontrerez probablement jamais) pour vous apporter des connaissances, des techniques et une méthodologie propre à  la plupart des sites web, que ce soit en webdesign, en intégration, en développement ou en gestion de projet.


Tutoriel webdesign

Page du tutoriel – ce qui a été crée dans Photoshop puis intégré en HTML5/CSS3 dans les précédentes parties



Ce tutoriel est découpé en 3 parties :

- La réflexion puis le webdesign : élaboration de la charte graphique et du design du site Internet

- L’intégration HTML5/CSS3

- Le développement PHP/MySQL des front et back office (administration)



3/3 : L’administration en PHP/MySQL

Cette troisième et dernière partie couvre les bases d’une administration à  savoir :

- créer la base de données

- créer la page d’authentification

- ajout / suppression d’une actualité- ajout / suppression d’une page du site

- affichage dynamique sur la page d’accueil (en front office) des dernières actualités

- récupération des adresses emails sur l’accueil pour la newsletter



Ces quelques points seront suffisants pour comprendre le fonctionnement et ce qui est nécessaire à  un site-vitrine administrable par une tierce personne. L’exemple est ici simple et basique pour ne pas se perdre dans les détails et éviter un tutoriel interminable. Cela vous permettra de réaliser des sites avec un espace d’administration et l’ajout / suppression de contenu dans une base de données et enfin de l’afficher sur la partie visible du site, aussi appelée front office.

Je remercie Jérôme, notre développeur professionnel, pour son coup de main sur cette troisième partie du tutoriel ! ;)


1. Redirection d’index.php

Le premier fichier que le visiteur verra en se connectant au site est bien entendu le fichier index. Pour notre administration, il ne contient que quelque lignes qui vont en fait rediriger l’utilisateur vers le formulaire de connexion :

<?php

header('Location: connexion.php'); # Redirection

exit();

?>

2. Créer la base de données

Que ce soit sur un serveur en ligne de votre hébergeur ou en local à  l’aide de Wamp, la procédure est la même, passant par PhpMyAdmin.

Plutôt que de créer les tables une à  une, nous sommes extrêmement généreux chez Living Tuts en vous donnant la base de donnée « realtea » déjà  crée et remplie ! :D

Depuis votre navigateur préféré, accédez donc à  PhpMyAdmin. Allez dans l’onglet « Importer » pour créer automatiquement la base de données et la remplir. Cliquez sur « Parcourir » et choisissez le fichier « database.sql » qui n’est autre qu’un fichier texte contenant les requêtes nécessaires à  la création et au remplissage des tables les unes après les autres. Vous pouvez l’ouvrir pour y trouver les requêtes nécessaires à  la création des tables, tout est expliqué juste en-dessous. Une fois le fichier sélectionné, cliquez sur « Exécuter » et c’est terminé ! Vous n’avez plus rien à  faire.

Création de la base de données

Création de la base de données

Normalement un message de confirmation a dû apparaître et vous annoncer que les tables ont été ajoutées.


Aller plus loin : les requêtes SQL expliquées

Depuis l’accueil de PhpMyAdmin (soit dans l’onglet Bases de données), créez la base de données en rentrant son nom « realtea ». Ne vous trompez pas dans le nom de la base, sinon il faudra penser à  le changer dans le fichier de connexion à  la base de données. Choisissez ensuite dans la liste déroulante l’interclassement « utf8_general_ci » qui est l’encodage standard, comme pour le format des fichiers des pages et le charset dans la balise meta des pages pour ne pas se faire chier avec les problèmes récurents d’accents.

Votre base est crée ! C’est aussi simple que ça ! Mais elle est vide. Oh.

La création des 3 tables n’a rien de compliqué mais quelques spécificités entrent en jeu, voici les requêtes permettant leur création. Chaque champ est explicité en-dessous. ;)


Table news

CREATE TABLE IF NOT EXISTS `news` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(150) NOT NULL,
`text` text NOT NULL,
`date` datetime NOT NULL,
`valid` tinyint(1) NOT NULL DEFAULT ’1′,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

[id]
C’est l’identifiant primaire de la table donc il est en auto incrémentation et non signé pour doubler le nombre de possibilités comme il n’y a pas d’id négatif.

smallint signed => – 32 767 à    32 767
smallint unsigned => 0 à  65 535 ( De quoi faire quelques news… )

[title]
Varchar 150 caractères ou plus il faut voir si on va avoir des titres concis ou un paragraphe entier. A moduler selon les besoins.

[-text]
Format Text ( pas de limite de taille ) dans la limite du raisonnable, ça prend de la place mais cela laisse le choix au niveau du content.

[date]
Le meilleur format pour travailler facilement sur des filtre de recherche ou des formatage de résultat dans les requêtes.

[valid]
Booléen (1 valide, 0 non valide) pour ne jamais avoir à  supprimer une entrée ( par défault à  1). Ceci est important à  noter, par exemple lorsque vous supprimez une actualité, vous ne l’effacez pas de la base de données mais son champ valid est uniquement passé à  0. Ainsi cela évite les erreurs irrécupérables de suppression de données ou encore de hacking.


Table users

CREATE TABLE IF NOT EXISTS `users` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`login` varchar(150) NOT NULL,
`pass` varchar(32) NOT NULL,
`mail` varchar(150) NOT NULL,
`valid` tinyint(1) NOT NULL DEFAULT ’1′,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

<pre>

[id]
Comme au-dessus.

[login]
Comme au-dessus.

[pass]
Cryptage md5 du mot de passe 32 caractères.

[mail]
Utile pour récupérer le mot de passe en cas de perte.

[valid]
Comme au-dessus.


Table newsletter

CREATE TABLE IF NOT EXISTS `newsletter` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`mail` varchar(150) NOT NULL,
`valid` tinyint(1) NOT NULL DEFAULT ’1′,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

[id]

Comme au-dessus.
[mail]

Comme au-dessus.
[valid]

Comme au-dessus.


Important : Pour la suite du tutoriel, veillez à  modifier les informations de connexion à  la base de données si vous n’avez pas les mêmes paramètres qu’ici (login : « localhost », mot de passe : « root »).


3. La page d’authentification

Comme pour toute administration, il faut un minimum de sécurité. La fameuse page d`identification est un classique duquel on ne se dérobe plus.

Créez un nouveau fichier PHP. Notre gentil développeur a pris soin de commenter le code. Dans les grandes lignes nous avons une partie HTML qui correspond au formulaire de connexion puis une partie en PHP au début qui n’intervient que si le formulaire a été soumis. On teste alors les données entrées (login et mot de passe) avec celles de la base de données et si tout est bon, on redirige vers la page d’accueil de l’administration, sinon on peut ajouter le comportement que l’on souhaite (message d’erreur…).

Il y a trois choses à  noter pour la sécurité :

- la première est la protection contre les injections SQL (cf code commenté en-dessous)

- les mots de passe sont encryptés en md5 pour augmenter la sécurité

- si la mot de passe est bon, on commence par créer un cookie pour garder la session ouverte. La durée de ce cookie est d’une heure, une durée relativement court vu qu’il s’agit d’une interface d’administration.

<?php

session_start(); # Ouverture des sessions

if(isset($_POST['id'], $_POST['mdp'])) # Si le formulaire est soumis
{
 $cnx = mysql_connect('localhost', 'root', '');        # Connexion
 mysql_select_db('realtea');

 $id = mysql_real_escape_string($_POST['id'], $cnx); # Protection des Injection SQL ect...
 $mdp = md5($_POST['mdp']);

 $query = mysql_query("SELECT * FROM users WHERE login = '$id' AND pass = '$mdp' AND valid = '1'"); # Vérification

 if(mysql_num_rows($query) > 0) # Si login pass et valid ok
 {
 setcookie('id', $id, time()+3600); # Création des cookies
 setcookie('mdp', $mdp, time()+3600);

 $_SESSION['id'] = $id; # Création des sessions
 $_SESSION['mdp'] = $mdp;

 header('Location: actu.php'); # Redirection

 exit();
 }
 else # Sinon
 {
 # Login ou Mot de passe incorrect
 }

 mysql_close($cnx); # Déconnexion
}

?>
<!DOCTYPE html>
<html lang="fr">
 <head>
 <meta charset="utf-8" />
 <title>Real Tea : Tutoriel pour Living Tuts - fr.livingtuts.com</title>

 <link rel="stylesheet" href="style.css" type="text/css" />

 <!--[if IE]>
 <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
 <!--[if lte IE 8]>
 <link rel="stylesheet" type="text/css" media="all" href="ie8.css"/><! [endif]-->
 <!--[if lte IE 7]>
 <link rel="stylesheet" type="text/css" media="all" href="ie7.css"/>
 <script src="js/IE8.js" type="text/javascript"></script><![endif]-->

 </head>

 <body>

 <!--[if IE]><div id="fond_ie"><! [endif]-->
 <nav id="menu_top">
 <ul>
 <li><a href="#">Actualités</a></li>
 <li><a href="#">Pages</a></li>
 <li><a id="deco" href="logout.php">Se déconnecter</a></li>
 </ul>
 </nav>
 <div></div>

 <div>

 <header id="header_top">
 <a id="logo" href="#">
 <h1><img src="images/logo.png" alt="Real Tea : société spécialisée dans le thé rare de qualité"/></h1>
 </a>

 </header>

 <section id="connexion">
 <form method="post" action="connexion.php">
 <label for="id">Identifiant</label>
 <input id="id" name="id" type="text" required /> <!-- Remplir ce champ est requis -->
 <br/>
 <label for="mdp">Mot de passe</label>
 <input id="mdp" name="mdp" type="password" required /> <!-- Remplir ce champ est requis -->
 <a href="#" id="pwd_oubli" >Mot de passe oublié ?</a>
 <input type="submit" value="Connexion">
 </form>
 </section>

 <div></div>

 <footer id="footer_site">
 <aside>
 <p>Retrouvez-nous aussi sur : </p><p style="float:left;"><a href="#"><img src="images/fb.png" alt="Joignez-nous sur Facebook"/></a> <a href="#"><img src="images/twitter.png" alt="Joignez-nous sur Twitter"/></a></p>
 </aside>

 <p id="copyright"> © Gaétan Weltzer   Tous droits réservés - tutoriel pour Living Tuts : <a href="http://www.livingtuts.com">www.livingtuts.com</a></p>

 <div></div>
 </footer>

 </div>
 <!--[if lte IE 8]></div> <! [endif]-->
 </body>
</html>


4. Ajouter/supprimer une actualité

Rappelons-nous du tout premier tutoriel à  l’étape de réflexion. Nous avions décidé très en amont que les utilisateurs (notre client fictif Real Tea) pourrait ajouter dynamiquement du contenu. Il s’agit des actualités présentes sur le site ainsi que de la création de nouvelles pages qui pourraient par exemple être : « Comment préparer nos thés » ou encore « Notre équipe », etc… Sur la page d’administration des actualités nous avons 4 choses pour rester simple et concis pour le tutoriel :

- ajout d’une nouvelle actu en remplissant un formulaire

- liste des actualités déjà  présentes sur le site

- suppression d’une actualité listée

- redirection vers une actu (bêtement, un lien « lire l’actualité » qui renvoie vers la page de l’actualité)

Pour ce qui est des explications, je n’ai pas grand chose à  dire, tout est commenté ! En une ligne, on teste au tout début si on a reçu le paramètre GET « delete », si tel est le cas, on supprime l’actualité qui a été supprimée. Si l’utilisateur a cliqué sur « Créer une actualité », on récupère les données (date, titre, texte) et on les rentre dans la base. Et enfin on cherche dans la base les actualités à  afficher sous le formulaire de la page.


<?php

session_start(); # Ouverture des sessions

date_default_timezone_set('Europe/Paris'); # Définition du Time Zone

if(isset($_COOKIE['id'])) $id = $_COOKIE['id']; # Récupération des Cookies & Ou Sessions
else if(isset($_SESSION['id'])) $id = $_SESSION['id'];
else $id = '';

if(isset($_COOKIE['mdp'])) $mdp = $_COOKIE['mdp']; # Récupération des Cookies & Ou Sessions
else if(isset($_SESSION['mdp'])) $mdp = $_SESSION['mdp'];
else $mdp = '';

$cnx = mysql_connect('localhost', 'root', '');        # Connexion
mysql_select_db('realtea');

$id = mysql_real_escape_string($id, $cnx); # Protection des Injection SQL ect...
$mdp = mysql_real_escape_string($mdp, $cnx);

$query = mysql_query("SELECT * FROM users WHERE login = '$id' AND pass = '$mdp' AND valid = '1'"); # Vérification

if(mysql_num_rows($query) == 0) # Si login pass et valid nok
{
 header('Location: connexion.php'); # Redirection

 exit();
}

if(isset($_GET['delete'])) # Si le paramètre delete est spécifié dans l'URL
{
 $id = mysql_real_escape_string($_GET['delete'], $cnx); # Protection des Injection SQL ect...

 mysql_query("UPDATE news SET valid = '0' WHERE id = '$id'"); # Valid à  0 pour la page $id
}

if(isset($_POST['date2'], $_POST['titre'], $_POST['desc'])) # Création d'une news
{
 $date = mysql_real_escape_string(date('Y-m-d', $_POST['date2']), $cnx); # Protection des Injection SQL ect...
 $title = mysql_real_escape_string($_POST['titre'], $cnx);
 $text = mysql_real_escape_string($_POST['desc'], $cnx);

 mysql_query("INSERT INTO news VALUES ('', '$title', '$text', '$date', '1')"); # Insertion dans la table d'une nouvelle news
}

$news = array();

$query = mysql_query("SELECT id, title, text, DATE_FORMAT(date, '%b') AS date_b, DATE_FORMAT(date, '%d') AS date_d, valid FROM news WHERE valid = '1'"); # Selection de toutes les news valides

while($result = mysql_fetch_array($query))
{
 $news[] = $result; # Replissage du tableau avec ces valeurs
}

mysql_close($cnx); # Déconnexion

?>
<!DOCTYPE html>
<html lang="fr">
 <head>
 <meta charset="utf-8" />
 <title>Real Tea : Tutoriel pour Living Tuts - fr.livingtuts.com</title>

 <link rel="stylesheet" href="style.css" type="text/css" />
 <link rel="stylesheet" type="text/css" href="inc/css/calendar-eightysix-v1.1-vista.css" media="screen" /> <!-- Template du calendar JS -->

 <!--[if IE]>
 <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
 <!--[if lte IE 8]>
 <link rel="stylesheet" type="text/css" media="all" href="ie8.css"/><! [endif]-->
 <!--[if lte IE 7]>
 <link rel="stylesheet" type="text/css" media="all" href="ie7.css"/>
 <script src="js/IE8.js" type="text/javascript"></script><![endif]-->

 <script type="text/javascript" src="inc/js/mootools-1.2.4-core.js"></script>   <!-- Frameworks JS Mootools Core -->
 <script type="text/javascript" src="inc/js/mootools-1.2.4.4-more.js"></script>   <!-- Frameworks JS Mootools More -->
 <script type="text/javascript" src="inc/js/calendar-eightysix-v1.1.js"></script>   <!-- Plugin Mootools Calendar Eightysix -->

 <script type="text/javascript">

 // Très bonne doc du calendar : http://dev.base86.com/scripts/mootools_javascript_datepicker_calendar_eightysix.html

 window.addEvent('domready', function()
 {
 MooTools.lang.set('fr-FR', 'Date', {
 months: ['Janvier', 'Févrié', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Decembre'],
 days: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
 dateOrder: ['date', 'month', 'year', '/']
 });

 MooTools.lang.setLanguage('fr-FR');

 new CalendarEightysix('date1',
 {
 'theme': 'vista',
 'defaultView': 'day',
 'startMonday': true,
 'format': '%d/%m/%Y',
 'createHiddenInput': true,
 'hiddenInputName': 'date2',
 'disallowUserInput': true
 });
 });

 </script>

 </head>

 <body>

 <!--[if IE]><div id="fond_ie"><! [endif]-->
 <nav id="menu_top">
 <ul>
 <li><a href="actu.php">Actualités</a></li>
 <li><a href="page.php">Pages</a></li>
 <li><a id="deco" href="#">Se déconnecter</a></li>
 </ul>
 </nav>
 <div></div>

 <div>

 <header id="header_top">
 <a id="logo" href="#">
 <h1><img src="images/logo.png" alt="Real Tea : société spécialisée dans le thé rare de qualité"/></h1>
 </a>

 </header>

 <section id="actu">
 <header>
 <h2>Ajouter / Supprimer une actualité</h2>
 </header>

 <p>Ici vous pouvez ajouter ou supprimer une actualité. Celle-ci apparaîtra automatiquement sur la page d'accueil et pourra ensuite être lue en entier lorsque le visiteur clique dessus.</p>

 <form method="post" action="actu.php">
 <label for="date1">Date</label>
 <input id="date1" name="date1" type="date" required /> <!-- Remplir ce champ est requis -->
 <br/>
 <label for="titre">Titre de l'actualité</label>
 <input id="titre" name="titre" type="text" required /> <!-- Remplir ce champ est requis -->
 <br/>
 <label for="desc">Description <em>(limité à  1000 caractères - il est conseillé de rester synthétique dans la description)</em></label>
 <textarea id="desc" name="desc"></textarea> <!-- Remplir ce champ est requis -->
 <br/>
 <input type="submit" value="Créer l'actualité">
 </form>

 <header id="header_liste_actu">
 <h2>Actualités déja publiées</h2>
 </header>

 <!-- boucle affichant les dernières actus -->
 <ul id="news">
 <?php

 $count = count($news); # Nombre de news

 for($i=0;$i<$count;$i++) # Boucle qui affiche les news
 {
 echo '
 <li>
 <article>
 <header>
 <h3><a href="#">'.$news[$i]['title'].'</a></h3>
 </header>

 <footer>
 <time datetime="2011-01-01" pubdate>'.$news[$i]['date_d'].' <span><br/>'.$news[$i]['date_b'].'</span></time> <!-- l\'atribut booléen pubdate signifie que le "time" spécifié est bien celui de l\'article au cas où il y aurait plusieurs <date> dedans-->
 </footer>

 <div>
 <p>'.$news[$i]['text'].'</p>
 <div>
 <p><a href="#">> Voir l\'actualité</a></p>
 <p><a href="actu.php?delete='.$news[$i]['id'].'">Supprimer</a></p>
 </div>
 </div><!-- /.entry-content -->

 </article>
 </li>';
 }

 ?>
 </ul>

 </section>

 <div></div>

 <footer id="footer_site">
 <aside>
 <p>Retrouvez-nous aussi sur : </p><p style="float:left;"><a href="#"><img src="images/fb.png" alt="Joignez-nous sur Facebook"/></a> <a href="#"><img src="images/twitter.png" alt="Joignez-nous sur Twitter"/></a></p>
 </aside>

 <p id="copyright"> © Gaétan Weltzer   Tous droits réservés - tutoriel pour Living Tuts : <a href="http://www.livingtuts.com">www.livingtuts.com</a></p>

 <div></div>
 </footer>

 </div>
 <!--[if lte IE 8]></div> <! [endif]-->
 </body>
</html>

5. Ajouter/supprimer une page

Cette interaction fonctionne en fait exactement comme pour les actualités. On peut en ajouter ou en supprimer, la requête ainsi que la page possèdent la même structure.

<?php

session_start(); # Ouverture des sessions

date_default_timezone_set('Europe/Paris'); # Définition du Time Zone

if(isset($_COOKIE['id'])) $id = $_COOKIE['id']; # Récupération des Cookies & Ou Sessions
else if(isset($_SESSION['id'])) $id = $_SESSION['id'];
else $id = '';

if(isset($_COOKIE['mdp'])) $mdp = $_COOKIE['mdp']; # Récupération des Cookies & Ou Sessions
else if(isset($_SESSION['mdp'])) $mdp = $_SESSION['mdp'];
else $mdp = '';

$cnx = mysql_connect('localhost', 'root', '');        # Connexion
mysql_select_db('realtea');

$id = mysql_real_escape_string($id, $cnx); # Protection des Injection SQL ect...
$mdp = mysql_real_escape_string($mdp, $cnx);

$query = mysql_query("SELECT * FROM users WHERE login = '$id' AND pass = '$mdp' AND valid = '1'"); # Vérification

if(mysql_num_rows($query) == 0) # Si login pass et valid nok
{
 header('Location: connexion.php'); # Redirection

 exit();
}

if(isset($_GET['delete'])) # Si le paramètre delete est spécifié dans l'URL
{
 $id = mysql_real_escape_string($_GET['delete'], $cnx); # Protection des Injection SQL ect...

 mysql_query("UPDATE pages SET valid = '0' WHERE id = '$id'"); # Valid à  0 pour la page $id
}

if(isset($_POST['titre'], $_POST['desc'])) # Création d'une page
{
 $title = mysql_real_escape_string($_POST['titre'], $cnx); # Protection des Injection SQL ect...
 $text = mysql_real_escape_string($_POST['desc'], $cnx);

 mysql_query("INSERT INTO pages VALUES ('', '$title', '$text', '1')"); # Insertion dans la table d'une nouvelle page
}

$pages = array();

$query = mysql_query("SELECT * FROM pages WHERE valid = '1'"); # Selection de toutes les pages valides

while($result = mysql_fetch_array($query))
{
 $pages[] = $result; # Replissage du tableau avec ces valeurs
}

mysql_close($cnx); # Déconnexion

?>
<!DOCTYPE html>
<html lang="fr">
 <head>
 <meta charset="utf-8" />
 <title>Real Tea : Tutoriel pour Living Tuts - fr.livingtuts.com</title>

 <link rel="stylesheet" href="style.css" type="text/css" />

 <!--[if IE]>
 <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
 <!--[if lte IE 8]>
 <link rel="stylesheet" type="text/css" media="all" href="ie8.css"/><! [endif]-->
 <!--[if lte IE 7]>
 <link rel="stylesheet" type="text/css" media="all" href="ie7.css"/>
 <script src="js/IE8.js" type="text/javascript"></script><![endif]-->

 </head>

 <body>

 <!--[if IE]><div id="fond_ie"><! [endif]-->
 <nav id="menu_top">
 <ul>
 <li><a href="actu.php">Actualités</a></li>
 <li><a href="page.php">Pages</a></li>
 <li><a id="deco" href="logout.php">Se déconnecter</a></li>
 </ul>
 </nav>
 <div></div>

 <div>

 <header id="header_top">
 <a id="logo" href="#">
 <h1><img src="images/logo.png" alt="Real Tea : société spécialisée dans le thé rare de qualité"/></h1>
 </a>

 </header>

 <section id="actu">
 <header>
 <h2>Ajouter / Supprimer une page</h2>
 </header>

 <p>Ici vous pouvez ajouter ou supprimer une page. Celle-ci apparaîtra automatiquement sur la page d'accueil et pourra ensuite être lue en entier lorsque le visiteur clique dessus.</p>

 <form method="post" action="page.php">
 <label for="titre">Titre de la page</label>
 <input id="titre" name="titre" type="text" required /> <!-- Remplir ce champ est requis -->
 <br/>
 <label for="desc">Description <em>(limité à  1000 caractères - il est conseillé de rester synthétique dans la description)</em></label>
 <textarea id="desc" name="desc"></textarea> <!-- Remplir ce champ est requis -->
 <br/>
 <input type="submit" value="Créer la page">
 </form>

 <header id="header_liste_actu">
 <h2>Pages déja crées</h2>
 </header>

 <!-- boucle affichant les dernières actus -->
 <ul id="news">
 <?php

 $count = count($pages); # Nombre de pages

 for($i=0;$i<$count;$i++) # Boucle qui affiche les pages
 {
 echo '
 <li>
 <article>
 <header>
 <h3><a href="#">'.$pages[$i]['title'].'</a></h3>
 </header>

 <div>
 <p>'.$pages[$i]['text'].'</p>
 <div>
 <p><a href="#">> Voir la page</a></p>
 <p><a href="actu.php?delete='.$pages[$i]['id'].'">Supprimer</a></p>
 </div>
 </div><!-- /.entry-content -->

 </article>
 </li>';
 }

 ?>
 </ul>

 </section>

 <div></div>

 <footer id="footer_site">
 <aside>
 <p>Retrouvez-nous aussi sur : </p><p style="float:left;"><a href="#"><img src="images/fb.png" alt="Joignez-nous sur Facebook"/></a> <a href="#"><img src="images/twitter.png" alt="Joignez-nous sur Twitter"/></a></p>
 </aside>

 <p id="copyright"> © Gaétan Weltzer   Tous droits réservés - tutoriel pour Living Tuts : <a href="http://www.livingtuts.com">www.livingtuts.com</a></p>

 <div></div>
 </footer>

 </div>
 <!--[if lte IE 8]></div> <! [endif]-->
 </body>
</html>


6. Se déconnecter

Il n’y a pas grand chose à  dire sur cette partie. On détruit la session ainsi que le cookie puis on redirige vers l’index.

<?php

session_start(); # Ouverture des sessions

session_unset(); # Destruction des sessions

setcookie('id', '', time()-3600); # Destruction des cookie
setcookie('mdp', '', time()-3600);

header('Location: connexion.php'); # Redirection

exit();

?>

7. On rend le site dynamique dans sa partie visible

A ce stade, on peut ajouter ou supprimer des contenus dans la base de données, mais ils ne sont pas encore visibles sur le front office ! Cela signifie que les visiteurs du site ne voient toujours que le texte écrit en dur en HTML à  l’étape 2 du tutoriel (l’intégration HTML). Il faut donc rajouter un peu de PHP dans la partie visible du site pour qu’il cherche les bonnes informations dans la base de données à  l’aide d’une requête puis qu’il l’affiche là  où nous le voulons depuis le départ. Cela signifie qu’il faudra veiller à  garder la même structure dans la page HTML en ajoutant le contenu dynamique dans la bonne balise au bon endroit pour ne pas perdre une classe ou un id et ainsi avoir un affichage erroné car aucun CSS n’est associé au texte.

Première chose à  faire : Reprenez les fichiers du front office (ne vous trompez pas !) et trouvez index.html. Pour que notre script marche, il faut transformer ce fichier html en fichier PHP, changer juste l’extension afin d’avoir « index.php ».

Note : dans les fichiers du tutoriel, le fichier index du site visible se nomme « index_front.php ».

Ensuite nous allons ajouter du php au tout début avant la première ligne :

<?php

$cnx = mysql_connect('localhost', 'root', '');        # Connexion
mysql_select_db('realtea');

if(isset($_POST['email'])) # Si le formulaire de newsletter est soumis
{
 $email = mysql_real_escape_string($_POST['email'], $cnx); # Protection des Injection SQL ect...

 mysql_query("INSERT INTO newsletter VALUES('', '$email', '1')"); # Insertion de l'adresse email dans la table
}

$news = array();

$query = mysql_query("SELECT id, title, text, DATE_FORMAT(date, '%b') AS date_b, DATE_FORMAT(date, '%d') AS date_d, valid FROM news WHERE valid = '1' ORDER BY DATE DESC LIMIT 0, 3"); # Selection des 3 dernières news valides

while($result = mysql_fetch_array($query))
{
 $news[] = $result; # Replissage du tableau avec ces valeurs
}

mysql_close($cnx); # Déconnexion

?>

Si vous avez suivi, nous nous connectons à  la base de données puis ensuite on teste si la variable « email » a été envoyé. Si tel est le cas, cela veut dire qu’un utilisateur a entré son adresse email pour s’inscrire à  la newsletter. Son adresse est donc entrée dans la table « newsletter » de notre base.

NB : Dans le cadre du tutoriel, nous partons du principe que l’input HTML5 de type « email » suffit à  prévenir au cas où l’utilisateur rentre du texte qui n’est pas sous forme d’un email, par exemple test@test.com. En condition réelle, pensez à  rajouter un test en PHP avant de l’entrer dans la base de données.

Ensuite, on récupère les trois dernières actualités valides. Il ne nous reste plus qu’à  les afficher là  où il faut, c’est-à -dire dans le bloc « actualités ».

<aside id="news">
 <header>
 <h2>ACTUALITES</h2>
 </header>
 <ul>
 <?php

 $count = count($news); # Nombre de news

 for($i=0;$i<$count;$i++) # Boucle qui affiche les news
 {
 echo '
 <li>
 <article>
 <header>
 <h3><a href="#">'.$news[$i]['title'].'</a></h3>
 </header>

 <footer>
 <time datetime="2011-01-01" pubdate>'.$news[$i]['date_d'].' <span><br/>'.$news[$i]['date_b'].'</span></time> <!-- l\'atribut booléen pubdate signifie que le "time" spécifié est bien celui de l\'article au cas où il y aurait plusieurs <date> dedans-->
 </footer>

 <div>
 <p>'.$news[$i]['text'].'</p>
 <p><a href="#">Lire la suite</a></p>
 </div><!-- /.entry-content -->

 </article>
 </li>';
 }

 ?>

 </ul>
 </aside>

Toute dernière chose : pour être sûr que votre formulaire pour la newsletter marche bien, veillez à  avoir rempli l’attribut action avec « index.php » comme il suit :

<form method="post" action="index.php">
<input name="email" type="email" placeholder="Mon adresse email" required> <!-- Remplir ce champ est requis -->
<br/>
<input type="submit" value="Je m'inscris">
 </form>

Et voilà , nous avons fait le tour de cet énorme tutoriel !

Pour résumer nous avons vu ensemble :

- la partie de réflexion et de début de gestion de projet afin de définir les besoins et contraintes du site

- le webdesign, création de la charte graphique et ergonomie

- intégration en HTML5/CSS3

- développement de l’administration permettant à  Real Tea de se connecter à  un back office pour ajouter/supprimer actualités et pages puis de les afficher dynamiquement dans la section visible du site ainsi que l’enregistrement de l’email de l’utilisateur pour la newsletter.


Je rappelle encore une dernière fois qu’il s’agit là  de la base d’un CMS. Cette administration de site pourrait être développée sans fin encore et encore au niveau des contenus, des messages, des fonctionnalités, de la sécurité, ajouter de l’AJAX, etc… On pourrait en faire un livre ! Néanmoins il vous apporte les connaissances nécessaires à  l’élaboration d’une petite administration, après c’est à  vous d’aller plus loin ! J’espère comme toujours qu’il répondra à  vos attentes et qu’il boucle ce très long tutoriel comme il se doit. Ce fut pour moi un plaisir de rédiger ce tutoriel en 3 parties, bien qu’éprouvant ! J’espère vous avoir enrichi par ma méthode de travail professionnelle et la technique ainsi que les connaissances nécessaires derrière.

Merci à  Jérôme, développeur de Living Tuts, pour le coup de main pour cette troisième partie du tutoriel.


Je vous dit à  bientôt pour un prochain tutoriel !

12 Comments to “Créer un site d`entreprise de A à  Z 3/3 : L’administration en PHP/MySQL”

  • Il serait peut-être plus judicieux d’utiliser PDO plutôt que mysql_connect et mysql_query…

    Sinon, tuto très interessant !

  • Merci pour cet énorme tuto, il m’a l’air très bien expliqué, c’est exactement ce que je cherchais (débutant en php mais grande soif de connaissances !)
    Comme on dit… Y’a plus qu’a ! Au boulot !!!
    Merci encore ;)

  • Bonjour,
    Les deux premières partie était vraiment bien, merci. Par contre celle-ci fait assez peur. Surtout que je suppose que beaucoup de tes lecteurs sont des dev juniors.

    Par exemple tu ne factorises absolument pas ton code. C’est assez rapide de faire un include « database.php ». De même pour la gestion de la sécurité.

    D’ailleurs, nul besoin de vérifier l’identité en base de la personne à chaque requete. Une fois qu’elle est logué, elle a automatique un cookie de session. Il suffit de placer un flag dans la session pour vérifier si l’utilisateur a bien des droits d’admin.
    Donc sur la page login, si c’est bon tu fais un $_SESSION['isAdmin'] = true sinon tu renvois la page de login.
    Et sur les pages d’admin tu regardes juste si true == $_SESSION['isAdmin'], si c’est faux, tu renvois la page de login. D’ailleur tu peux factoriser ce code.
    Enfin, il est recommandé de sallé le mot de passe ;) .

    De même, il serait plus intéressant d’utiliser PDO car il permet de préparer tes requêtes SQL et donc d’empêcher les injections SQL.

    Ensuite tu n’echapes pas tes résultats de BDD, tu peux donc avoir des failles XSS.

    Ensuite une technique assez cool pour gerer les formulaire est de préparer un tableaudes champs, puis un autre des erreurs. (exemple …)
    $form = array(
    ‘newsletter’ => array(
    ‘email’ =>  »
    ‘active’ =>  »
    )
    )
    $errors = array(
    ‘newsletter’ => array(
    ‘email’ =>  »
    ‘active’ =>  »
    )
    )

    ensuite de setter les valeurs si elles existe depuis le tabeau $_POST
    if (isset ($_POST['newsletter']))
    {
    $form['newsletter'] = $_POST['newsletter']
    }
    Puis de valider tes données :
    if (isset ($_POST['newsletter']))
    {
    if ($form['newsletter']['email'] n’est pas un email (oui pseudo code, dsl, il est tard, dsl))
    {
    $error['newsletter']['email'] = ‘L\’email n’est pas valide’
    }
    // Les autres validateurs…
    }

    Et enfin d’afficher ton form :

    <input type="text" name="newsletter[email]" value="
    ….

    comme ca, si l’utilisateur se trompe, il aura quand meme les valeurs qu’il a saisi…

    Cerise sur le gateau : les ?> en fin de fichier ne sont pas utile ;)

    Voila tout plein de bonne pratique, j’espère qu’elles te seront utile

    Greg :)

  • Bonjour, cela ne fait pas très longtemps que je manipule le PHP/MySQL. Je ne comprends pas pourquoi je n’arrive pas à me connecter sur Realtea avec le login (admin) et mot de passe(63a9f0ea7bb98050796b649e85481845) donné. Quelle est mon erreur ?
    J’ai modifié le login et le mot de passe dans Users, mais je n’ai non plus pas réussi à me connecter en utilisant ces données.
    Pouvez vous m’aider ?

  • Je rejoins Greg sur les points qu’il a précisé dans ses commentaires. Concernant l’utilisation de l’extension mysql dans le tuto je trouve que c’est une erreur assez importante dans la mesure ou cette extension n’est plus développé depuis la sortie de PHP 5.0 (soit depuis 2004) et qu’elle n’est conservé dans le langage que pour des raisons de compatibilité. Si on ne souhaite pas utiliser PDO il faut donc se rabattre sur mysqli qui est l’extension MySQL par défaut en PHP 5.

    D’une manière générale ce tuto est très en dessous des superbes cours qu’on trouve sur votre site et il ne mérite pas la qualification de « technique de professionnel ».

    En tout cas bravo pour le site qui est vraiment terrible.

  • Juste deux truc que j’ai zappé :

    Concernant le ?> de fin. Quand un fichier ne contient que du code PHP, par convention on ne met pas le tag de fin (?>) pour éviter d’injecter un espace accidentellement car cela peut potentiellement casser les fonctions header() et session_*. Ça fait partie des « coding standard » de Zend (qui je rappelle est la boite qui a créé le moteur de script et le parseur de PHP).

    Plusieurs fois dans votre code on voit des trucs comme ça :

    $pages = array();

    $query = mysql_query(« SELECT * FROM pages WHERE valid = ’1′ »); # Selection de toutes les pages valides

    while($result = mysql_fetch_array($query))
    {
    $pages[] = $result; # Replissage du tableau avec ces valeurs
    }

    Parcours des résultats pour remplir un tableau. Avec mysqli ou PDO ça se fait en une seule ligne sans besoin de parcourir le tableau 2 fois.

  • @Greg @jb_gfx et aux autres : Je parle en mon nom et non plus comme intermédiaire avec le développeur. Il semble qu’effectivement le code est loin d’être optimal et vous avez raison de l’avoir souligné ! Nous sommes désolé de ce manque de qualité et nous allons faire corriger le tutoriel au plus vite par un développeur compétent, à moins que l’un de vous ne se propose !

    Merci et à bientôt. :)

  • Bonsoir , petit soucis de connection avec admin et 63a9f0ea7bb98050796b649e85481845 ça ne marche pas ainsi que localhost / root et en rentrant moi même dans la table users (un login et un pass) rien ne ce passe.
    Je ne comprends pas, si vous avez une solution merci beaucoup :)

  • Bonjour le tuto est vraiment sympa! serais t-il possible de l’enrichir un peu?
    Comme par exemple changer les couleurs de fond la bannières ect.. tout
    ça avec l’espace administration de plus il n’y a aucun tuto la dessus ou du moins pas à ma connaissance….
    En tout cas félicitation pour ce tuto :)

  • Merci beaucoup pour le tuto!

    PS: les 2 autres parties sont affichable avec le mode « lecteur de safari » mais pas celle ci ;)

    Bonne continuation.

  • En effet, le login / mot de passe sont localhost / root.
    Merci pour vos commentaires !

  • >Concernant les cookies / sessions :
    Ton dev fait au final comme il veut. Mais c’est vraiment un très très mauvaise pratique. Si vous voulez que l’utilisateur reste connecté même après avoir fermé son navigateur, il faut stocker un token chez le client, et le même en base.

    >pour le sallage de mot de passe>
    http://www.commentcamarche.net/faq/8821-comment-bien-stocker-et-verifier-un-mot-de-passe

    >PDO
    pdo n’est pas utilsé que pour les projets qui changent de BDD. Il permet de préparer ses requêtes et d’avoir un code agnostique. Du coup on ne peut pas avoir d’injection sql.

    >echapement de la vue.
    Non elle ne sont pas échapper dans la base. D’ailleurs ce n’est surtout pas au moment de l’insertion d’échaper. C’est toujours à la vue. Dans votre application il suffit d’avoir un compte admin pour faire des failles xss.

    > ?>
    moi aussi je suis contre les shorts tags, ca ne change rien

    => Sinon je comprends que ton dev soit un peu réfractaire à ma « revue de code » un peu dur. La culture de la revue de code n’est pas encore assez ancré dans les mœurs. Dans ma boite tout le monde en a. Et je trouve ca génial. Ca fait extrêmement progresser. Pour info travail chez sensiolabs, qui est (en autre) le créateur de symfony …

Laisser un commentaire

Write for usMes Tutoriels Favoris

Vous devez être loggué pour pouvoir ajouter des tutoriels à cette liste.

Connexion

Write for usEcrivez pour nous

- Vous voulez aider la communauté et partager votre savoir ?

- Vous voulez acquérir de la visibilité sur Internet ?

Ecrivez pour nous