Ce tutoriel est comme le précédent basé sur celui de Six Revisions (partie front-end statique). D’ailleurs si vous n’êtes pas allé voir le premier tutoriel je vous recommande très fortement d’aller y faire un tour!
Qu’allons nous faire?
Une question qui se doit d’être posée, puisqu’il est important de savoir quelles fonctionnalités nous allons développer avant de toucher à quelque chose.
Cette partie administration permettra donc de:
- Ajouter un slide vide (jQuery)
- Ajouter un slide (avec Titre, lien, description et image redimensionnée) (PHP/MySQL)
- Supprimer un slide (jQuery-Ajax)
- Modifier un slide (PHP/MySQL)
- Changer l’ordre des slides. (jQuery-Ajax)
Suivant les fonctionnalités nous utiliserons 2 technologies: PHP et jQuery, qui avec de l’Ajax, permettra de ne recharger qu’une partie de la page.
Nous ne traiterons pas de la protection de l’accès à la page d’administration, puisque cela a déjà été l’objet d’un tutoriel. Voici comment nous allons organiser nos fichiers:

Ne prenez pas du tout ce modèle pour une vérité absolue, il est conçu pour une meilleur compréhension du tuto pour ne pas avoir trop de fichiers. Ainsi une fois ce tutoriel intégré à votre site, il sera préférable par exemple d’inscrire vos scripts javascript dans des fichiers externes, avoir 2 feuilles de styles différentes pour la partie site et administration. Bref c’est à vous de l’adapter à vos besoins et vos exigences
Etape 1 : La base de données
Nous allons stocker les différentes informations contenues dans les slides dans une base de données. Pour cela, nous allons avoir besoin de créer une table SQL contenant ces champs:
- id : l’identifiant du slide
- titre : titre du slide
- lien : lien hypertexte
- texte : description du slide
- img : nom de l’image à afficher
Le script pour créer cette table est le suivant, vous pouvez l’intégrer avec PHPMyAdmin :
CREATE TABLE slider ( id tinyint(4) NOT NULL auto_increment, titre varchar(100) NOT NULL, lien varchar(100) NOT NULL, texte tinytext NOT NULL, img varchar(100) NOT NULL, PRIMARY KEY (id) ) TYPE=MyISAM ;
Etape 2 : Structure de la page d’administration
Voici la structure PHP/HTML avec laquelle nous allons partir, chaque slide correspondra à un formulaire que nous appelons et affichons dynamiquement via une requête SQL
<body class="admin">
<div id="pageContainer">
<h1>Administration</h1>
<a href="javascript:ajouteSlideVide()" class="ajoutSlide">Ajouter un slide</a>
<div id="formulaires">
<?php
$connect = mysql_connect(MYHOST, MYUSER, MYPASS) or die ('Identifiants incorrects');
mysql_select_db(MYDB) or die ('Base de données incorrecte');
$requete = "SELECT id,titre,lien,texte,img FROM slider ORDER BY id";
$result = mysql_query($requete);
if(mysql_num_rows($result)){
while($cur_item = mysql_fetch_assoc($result)){
echo '
<;form method="post" enctype="multipart/form-data">
<fieldset>
<legend>'.$cur_item['id'].'</legend>
<input type="hidden" name="slide" id="idslide" value="'.$cur_item['id'].'" />
<input type="hidden" name="modif" id="modif" value="true" />
<label>Titre</label>
<input type="text" name="titre" value="'.htmlspecialchars($cur_item['titre']).'"/>
<label>Lien</label>
<input type="text" name="lien" value="'.htmlspecialchars($cur_item['lien']).'" />
<label>Description</label><textarea name="description">'.htmlspecialchars($cur_item['texte']).'</textarea>
<label>Image</label>
<input name="image" type="file" />
<img class="miniature" src="'.htmlspecialchars($dossierImages.$cur_item['img']).'" alt="image du slide" />
<button>Modifier</button>
<a class="supprimer" href="javascript:void(0)">Supprimer</a>
<a class="positionplus" href="javascript:void(0)">+</a>
<a class="positionmoins" href="javascript:void(0)">-</a>
';
}
} else{
echo '
<form enctype="multipart/form-data" method="post">
<fieldset>
<legend>1</legend>
<input id="idslide" name="slide" type="hidden" value="1" />
<label>Titre</label>
<input name="titre" type="text" />
<label>Lien</label>
<input name="lien" type="text" />
<label>Description</label><textarea name="description"></textarea>
<label>Image</label>
<input name="image" type="file" />
<button>Ajouter</button>
<a class="supprimer" href="javascript:void(0)">Supprimer</a>
<a class="positionplus" href="javascript:void(0)">+</a>
<a class="positionmoins" href="javascript:void(0)">-</a></fieldset>
</form>
';
}
mysql_close();
Chaque formulaire contient 2 champs de type hidden, c’est à dire des champs contenant des informations mais pas affichées à l’écran. L’un contiendra le numero du slide, l’autre informera s’il s’agit d’un ajout ou d’une modification (le traitement n’est pas le même en fonction). Notez aussi les 3 liens (supprimer, position+ et position -) qui ne renvoient pas véritablement de fonctions, mais dans le code Javascript nous leur attribuerons des évènements de type clic en fonction de leur classe.
Enfin dernier petit point, il est indispensable d’ajouter un attribut enctype= »multipart/form-data » à votre formulaire, afin de pouvoir uploader des images via celui-ci.
Etape 3 : Ajouter un slide vide
Nous allons commencer la partie Javascript en renseignant la fonction ajouteSlide(). Comme nous allons travailler avec la librairie jQuery, il est essentiel de l’inclure avant de l’utiliser. Pensez aussi à bien vérifier que vous avez une version de jQuery supèrieure à la 1.3.
function ajouteSlideVide(){
var numeroSlide = $('#formulaires form').length+1;
$("#formulaires form:last").clone().appendTo('#formulaires').hide().fadeIn();
//Réinitialise les valeurs du formulaire
$('#formulaires form:last legend').html(numeroSlide);
$('#formulaires form:last input').val('');
$('#formulaires form:last textarea').val('');
$('#formulaires form:last img').remove();
$('#formulaires form:last #idslide').val(numeroSlide);
$('#formulaires form:last #modif').val('false');
$('#formulaires form:last button').text('Ajouter');
}
Tout d’abord, on récupère la position du dernier slide (et par conséquent cela définira l’identifiant du nouveau. L’instruction $(« #formulaires form:last »).clone().appendTo(‘#formulaires’).hide().fadeIn(); peut paraître un peu barbare, mais elle signifie juste qu’on prend le dernier formulaires de notre liste, on le copie, puis on le colle en dernier dans notre liste de formulaires. Et comme j’aime bien les trucs jolis je le cache directement, et le fais apparaitre en fondu.
Une fois qu’on a ce nouveau formulaire, il faut réinitialiser ses valeurs. Pour manipuler ces informations, il faut principalement utiliser des méthodes jQuery comme html() ou val() qui change l’attribut value d’un champ ou le contenu d’un textarea. Et enfin, la méthode remove() pour supprimer un élément.
Etape 4 : Ajouter et modifier (PHP)
Voici le code à placer au début de votre fichier index.php
<?php
define('ROOT','../');
$dossierImages = ROOT.'img/images-slider/';
require(ROOT.'config/config.php');
require('SBImage.php');
function verifieTypeMime($type){
$typesacceptes = array('image/jpeg','image/jpg','image/png','image/gif','image/pjpeg');
if(in_array($type,$typesacceptes)) return true;
else return false;
}
$connect = mysql_connect(MYHOST, MYUSER, MYPASS) or die ('Identifiants incorrects');
mysql_select_db(MYDB) or die ('Base de données incorrecte');
if(isset($_POST) && !empty($_POST)){
if(
!empty($_POST['slide'])&&
!empty($_POST['titre'])&&
!empty($_POST['lien'])&&
!empty($_POST['description'])){
$import = false;
if(isset($_FILES['image'])){
if(verifieTypeMime($_FILES['image']['type'])){
$import = true;
$fichier = $dossierImages.$_FILES['image']['name'];
copy($_FILES['image']['tmp_name'],$fichier);
SBImage::resize($fichier,210,160,true);
}
}
$requete = '';
$reqFile = '';
if($_POST['modif'] == "true"){
if($import)
$reqFile = ",img='".$_FILES["image"]["name"]."'";
$requete .= "UPDATE slider SET titre='".$_POST['titre']."',lien='".$_POST['lien']."',texte='".$_POST['description']."'".$reqFile." WHERE id='".$_POST['slide']."'";
}else{
if($import)
$reqFile = $_FILES["image"]["name"];
$requete = "INSERT INTO slider(id,titre,lien,texte,img)
VALUES('".$_POST['slide']."',
'".$_POST['titre']."',
'".$_POST['lien']."',
'".$_POST['description']."',
'".$reqFile."'
)";
}
mysql_query($requete);
}
}
?>
Quelques explications s’impsent: En premier lieu, nous définissons une constante qui déterminera l’emplacement du répertoire racine par rapport au répertoire dans lequel on se trouve, ici comme on est dans le répertoire admin, il faut remonter d’un niveau donc : ‘../’ . Puis on définit le chemin vers les images et l’on inclut le fichier de configuration et la classe qui gère les images.
La fonction verifieTypeMime, comme son nom vérifie le type Mime des images uploadées, cela garantit une sécurité accrue puisque vous serez sur d’avoir affaire à de véritables images.
Les 2 lignes suivantes servent à se connecter à la base de donnée. Le reste du code est éxécuté si et seulement si un formulaire a été validé et qu’il contient tous les éléments. De la même manière que pour récupérér des valeurs avec la variable superglobale $_POST, on récupère un fichier uploadé avec la variable $_FILES, ['image'] correspondant dans cette situation à l’attribut name du champ input de type File. Ensuite il suffit de copier ce fichier (par défaut il se copie automatiquement dans un dossier temporaire de votre serveur) dans le bon répertoire et d’effectuer un traitement dessus avec la méthode Resize de la classe SBImage, disponnible en fichier texte, ou en téléchargeant directement la source.
A partir de là, on veut savoir s’il s’agit d’une modification ou d’une insertion. C’est là qu’entre en compte le champ caché que nous avions mis dans notre formulaire. Selon sa valeur la requête SQL n’aura pas du tout la même tête: Dans un cas on utilise INSERT INTO maTable(meschamps,a,b,c) VALUES(valA,valB,…) et dans l’autre cas: UPDATE maTable SET monChampA=valA, … WHERE id=idDuSlide.
Etape 5 : Supprimer un slide (JS)
Comme vous avez pu le voir au début de ce tutoriel, j’ai parlé de certaines fonctionnalités qui seront développées avec Ajax, la suppression de slide en fait partie. Si vous souhaitez en savoir plus sur l’Ajax et son fonctionnement, je vous recommande d’aller voir un tutoriel qui vous initiera à cette technologie. Le principe est ici de faire en sorte que tous les clics qui seront effectuées sur des balises qui porteront la classe « supprimer » renverront vers une fonction javascript qui contiendra un appel Ajax vers un script PHP. Je suis sur qu’avec le code vous comprendrez mieux :
$(document).ready(function(){
$('.supprimer').live('click',function(){
var idSup = $(this).parent().find('legend').html() * 1;
var form = $(this).parent().parent();
$.get("ajax.php",{idSup: idSup},
function(data){
form.fadeOut('fast',function(){
form.remove();
});
for(var i=idSup; i<(Number(form.nextAll().size())+idSup);i++){
$('#formulaires form:eq('+i+')').find('legend').text(i);
$('#formulaires form:eq('+i+')').find('#idslide').val(i);
}
}
);
});
La première ligne signifie que ce code sera éxécuté dés que le document (l’arbre DOM) sera complètement chargé. Ce détail a toute son importance, sinon il ne reconnaitra aucune classe « supprimer » et passera à la suite.
La méthode « live » utilisée est en fait l’équivalent de « bind », la première permet (depuis jQuery 1.3) d’ajouter aussi des écouteurs aux objets qui sont crées par la suite en Javascript. Dans notre cas, cette démarche est essentielle puisqu’il peut être utile de vouloir supprimer un formulaire qu’on vient d’ajouter (même si cela paraît un peu idiot). En résumé, cette fonction live permet donc d’ajouter un écouteur qui comme son nom l’indique écoute et éxécute la fonction si les objets qui ont la classe « supprimer » ont reçu un évènement : en l’occurence, un clic ici.
Une fois dans cette fonction, il faut récupérer l’identifiant du slide qui y est associé. Le procédé est là aussi un peu compliqué: On récupère l’objet actuel ($(this)), puis son élément parent (parent()), qui n’est rien d’autre que le formulaire et enfin on cherche la balise legend (find(‘legend’)) puis sa valeur (html()) que l’on multiplie par 1 (petite astuce Javascript pour convertir une chaîne en nombre).
Enfin la requête Ajax qui apelle le fichier PHP : « ajax.php », avec comme paramètre (passé en variable $_GET), l’identifiant du slide que l’on veut supprimer. Le 3ème paramètre est la fonction que l’on éxécute lorsque la requête est terminée. Nous n’aurons plus qu’à faire disparaître le formulaire. Puis modifier les identifiants des formulaires qui suivent. Attention, ici on ne change que l’HTML, si on ne fait rien dans notre script « ajax.php », les slides auront les mêmes identifiants, et aucun ne sera supprimé.
Etape 6 : Supprimer un slide (PHP)
La dernière étape a consisté à supprimer visuellement un slide, ici nous le supprimerons dans la Base de données, et nous le ferons dans le script « ajax.php » qui est appelé en Ajax.
<?php
define('ROOT','../');
$dossierImages = ROOT.'img/images-slider/';
require(ROOT.'config/config.php');
$connect = mysql_connect(MYHOST, MYUSER, MYPASS) or die ('Identifiants incorrects');
mysql_select_db(MYDB) or die ('Base de données incorrecte');
if(isset($_GET['idSup']) && is_numeric($_GET['idSup'])){
//Suppression de l'image et de la ligne dans la bdd
$result = mysql_query('SELECT img FROM slider WHERE id="'.$_GET['idSup'].'"');
//Supprimer l'image associée (ou pas si elle est utilisée dans un autre slide)
$cur = mysql_fetch_assoc($result);
$resultImageIdentique = mysql_query('SELECT COUNT(*) FROM slider WHERE img="'.$cur['img'].'"');
$count = mysql_fetch_assoc($resultImageIdentique);
if($count['COUNT(*)']<=1)
unlink($dossierImages.$cur['img']);
mysql_query('DELETE FROM slider WHERE id="'.$_GET['idSup'].'"');
mysql_query('UPDATE slider SET id=id-1 WHERE id>'.$_GET['idSup']);
mysql_close();
}
?>
Dans un premier temps, on supprime l’image qui est associée au slide que l’on veut supprimer avec la fonction unlink(). Une fois cette opération faite il suffira de supprimer de la Base de donnée la ligne du slide (avec DELETE FROM maTable WHERE id=idDuSlideaSupprimer). Enfin on met a jour les identifiants de tous les slides suivant: afin de toujours avoir une suite continue. Ce traitement se fait avec la requête SQL : UPDATE maTable SET id=id-1 WHERE id>idASupprimé.
Etape 7 : Changer la position d’un slide (JS)
L’intérêt d’avoir une partie administration est aussi de pouvoir changer la position d’un slide très facilement. Nous verrons dans cette étape, comment changer la position d’un formulaire dans l’arbre DOM avec jQuery, puis dans l’étape suivante les opérations à effectuer côté serveur.
$('.positionplus').live('click',function(){
var position = $(this).parent().find('legend').html();
var form = $(this).parent().parent();
if (form.is(':last-child')) {
alert('Eh oh je veux rester sur le diaporama moi!');
return false;
}
position++;
var positionplus = position;
position--;
var positionmoins = position;
$(form.next()).after(form);
form.find('legend').text(positionplus);
form.find('#idslide').val(positionplus);
$(form.prev()).find('legend').text(positionmoins);
$(form.prev()).find('#idslide').val(positionmoins);
$.get("ajax.php",{idChange1: positionplus,
idChange2:positionmoins
});
});
Une fois de plus, le code peut sembler un peu barbare mais ce sont les mêmes méthodes jQuery qui reviennent souvent. Pour cette fonction, il faut biensur vérifier si le slide n’est évidemment pas le dernier de la liste auquel cas on informe l’utilisateur qu’il n’y aura aucun changement de position.On utilise donc pour cela, la fonction is(‘:last-child’) qui retourne true s’il s’agit bien du dernier formulaire se trouvant dans la div #formulaires.
Autre subtilité : pour replacer le formulaire à sa bonne place, on utilise $(form.next()).after(form);. form.next() récupère le formulaire suivant, et on lui indique de le placer après celui ci avec .after().
Voici la fonction inverse:
$('.positionmoins').live('click',function(){
var position = $(this).parent().find('legend').html();
var form = $(this).parent().parent();
if (form.is(':first-child')) {
alert('Quoi? tu veux l\'afficher avant le début???');
return false;
}
position--;
var positionmoins = position;
position++;
var positionplus = position;
form.insertBefore(form.prev());
form.find('legend').text(positionmoins);
form.find('#idslide').val(positionmoins);
$(form.next()).find('legend').text(positionplus);
$(form.next()).find('#idslide').val(positionplus);
$.get("ajax.php",{idChange1: positionplus,
idChange2:positionmoins
});
});
});
Comme vous pouvez le voir le fonctionnement est très semblable à la fonction précédente.
Etape 8 : Changer la position d’un slide (PHP)
Maintenant nous allons nous occuper de la partie PHP et dans le fichier « ajax.php », faire en sorte d’intervertir 2 identifiants dans notre base de données. Voici le bout de code à placer à la suite de ce qui est déjà écrit:
if(isset($_GET['idChange1'])&& is_numeric($_GET['idChange1'])
&& isset($_GET['idChange2'])&& is_numeric($_GET['idChange2'])){
$result = mysql_query('SELECT id,titre,lien,texte,img FROM slider WHERE id='.$_GET['idChange1'].' OR id='.$_GET['idChange2'].'');
while($cur_item = mysql_fetch_assoc($result)){
if($cur_item['id'] == $_GET['idChange1'])
$id = $_GET['idChange2'];
else
$id = $_GET['idChange1'];
mysql_query('UPDATE slider SET titre = "'.$cur_item['titre'].'",
lien = "'.$cur_item['lien'].'",
texte = "'.$cur_item['texte'].'",
img = "'.$cur_item['img'].'"
WHERE id="'.$id.'"');
}
}
En fait l’identifiant étant un champ unique, on ne peut pas effectuer d’opérations simples comme un UPDATE sur l’identifiant, car 2 champs seraient à un instant donné équivalents, ce qui provoquerait une erreur logique. L’alternative consiste donc à modifier tous les autres champs (titre, lien,texte, img).
Etape 9 : Et le CSS
Enfin, pour embellir notre page d’administration je vous propose ce CSS:
/***********
* Admin
* ****************/
.ajoutSlide{
display:block;
background-image:url('img/ajoute_slider.png');
width:119px;
height:22px;
text-indent:-9999px;
outline:none;
}
.admin{
background-image:none;
}
.admin #pageContainer{
width:80%;
margin:auto;
}
.admin #pageContainer h1{
background:transparent url(img/admin.png) no-repeat top left;
}
.miniature{
height:50px;
clear:left;
display:block;
position:relative;
left:80px;
height:60px;
padding:3px;
margin:3px 0px 3px 0px;
background-color:#555;
}
.supprimer{
background: transparent url('img/btn_suppr.png') no-repeat;
width:14px;
height:15px;
display:block;
text-indent:-9999px;
outline:none;
float:right;
}
form{
display:block;
float:left;
width:300px;
}
fieldset{
border:1px solid #525050;
padding:7px;
margin:3px;
}
legend{
font-size:1.8em;
display:block;
margin-left:250px;
position:absolute;
}
label{
display:block;
float:left;
width:70px;
text-align:right;
margin:3px;
}
button{
display:block;
clear:left;
color:#555;
margin-left:80px;
}
input,textarea{
float:left;
width:180px;
margin:3px;
color:#555;
}
textarea{
height:100px;
}
Dernière étape : Le slideshow
A partir de là il faut reprendre le 1er tutoriel et au lieu d’y inscrire les div à la main, nous allons faire une boucle PHP/SQL pour les afficher dynamiquement ce qui nous donnera ceci:
<!-- Slideshow HTML -->
<div id="slideshow">
<div id="slidesContainer">
<?php
define('ROOT','./');
$dossierImages = ROOT.'img/images-slider/';
require(ROOT.'config/config.php');
$connect = mysql_connect(MYHOST, MYUSER, MYPASS) or die ('Identifiants incorrects');
mysql_select_db(MYDB) or die ('Base de données incorrecte');
$requete = "SELECT id,titre,lien,texte,img FROM slider ORDER BY id";
$result = mysql_query($requete);
if(mysql_num_rows($result)){
while($cur_item = mysql_fetch_assoc($result)){
?>
<div class="slide">
<h2><?php echo $cur_item['titre'];?></h2>
<?php
if(!empty($cur_item['lien']) && is_file($dossierImages.$cur_item['img'])){
echo '<a href="'.$cur_item['lien'].'" title="'.$cur_item['lien'].'">
<img src="'.$dossierImages.$cur_item['img'].'" alt="'.$cur_item['lien'].'"/></a>';}
echo $cur_item['texte'];?>
</div>
<?php
}
}
?>
</div>
</div>
<!-- Slideshow HTML -->
Ce tutoriel est enfin terminé. Il est un peu difficile et surtout très long mais il permet de bien réviser les bases de PHP. De plus il est un excellent exercice pour s’approprier jQuery. Merci encore à SixRevisions et à Jacob Gube pour la base qu’il a apporté.



