Bonjour tout le monde,
Voilà, j'aurais besoin d'aide concernant une "amélioration" que j'aimerais apporter au Tuto Calendrier en PHP.
Je me sers du calendrier comme planning de réservation.
La problématique : Jusqu'à maintenant, en suivant le tuto, il suffisait d'insérer une ligne dans la base de données pour pouvoir la lire et l'intégrer au calendrier. C'est à la base un système d'événement. Donc une ligne = un événement.
J'aimerais, au lieu d'intégrer 1 seule ligne avec 1 seule date, mettre en place une plage de date.
Pour être plus claire, j'ai pour l'instant une table dans ma bdd de se type :
id : int(11)
dispo : boolean
statut : varchar(255)
date : date
Pour le moment, si dans ma bdd j'ai une ligne " 1, 1, 'Réservé', '01012014' ", alors la case du calendrier correspondant au 01012014 sera marquée comme événement.
Maintenant, j'aimerais avoir une table dans ma bdd de se type :
id : int(11)
datedebut : date
datefin : date
dispo : boolean
statut : varchar(255)
Si dans ma bdd j'ai une ligne " 1, '0101214', '14012014', 1, 'Réservé' ", je voudrais que toutes les dates comprises entre 01012014 et 14012014 soient marquées comme événement.
Voilà, donc pour le moment, on peut dire que 1 ligne = 1 date. Comment faire pour avoir 1 ligne = plusieurs dates ?
Merci d'avance !
Ma page calendrier.php :
<?php
require('../includes/config.php');
require('../includes/date.php');
$date = new Date();
$year = date('Y');
$events = $date->getEvents($year);
$dates = $date->getAll($year);
?>
<div class="periods">
<!-- ######################### BLOC ANNÉE ############################ -->
<center><div class="year"><?php echo $year; ?></div></center>
<!-- ######################### FIN BLOC ANNÉE ######################## -->
<!-- ######################### BLOC MOIS ############################# -->
<div class="months">
<ul>
<?php foreach($date->months as $id=>$m): ?>
<center><li><a href="" id="linkMonth<?php echo $id+1; ?>"><?php echo utf8_encode(substr(utf8_decode($m),0,3)); ?></a></li></center>
<?php endforeach; ?>
</ul>
</div>
<!-- ######################### FIN BLOC MOIS ######################### -->
<div class="clear"></div>
<?php $dates = current($dates); ?>
<?php foreach ($dates as $m=>$days): ?>
<!-- ######################### BLOC TABLEAU ####################### -->
<div class="month relative" id="month<?php echo $m; ?>">
<table>
<thead>
<!-- ######################### BLOC JOUR ####################### -->
<tr>
<?php foreach ($date->days as $d): ?>
<th><?php echo substr($d,0,8); ?></th>
<?php endforeach; ?>
</tr>
<!-- ######################### FIN BLOC JOUR ####################### -->
</thead>
<tbody>
<tr>
<?php $end = end($days); foreach($days as $d=>$w): ?>
<?php $time = strtotime("$year-$m-$d"); ?>
<?php if($d == 1 AND $w-1 > 0): ?>
<td colspan="<?php echo $w-1; ?>" class="padding"></td>
<?php endif; ?>
<td<?php if(isset($events$time])): ?> class="evenement"<?php endif; ?>>
<div class="relative">
<div class="day"><?php echo $d; ?></div>
</div>
<div class="daytitle">
<?php echo $date->days$w-1]; ?> <?php echo $d; ?> <?php echo $date->months$m-1]; ?>
</div>
<ul class="events">
<?php if(isset($events$time])): foreach($events$time] as $e): ?>
<li><?php echo $e; ?></li>
<?php endforeach; endif; ?>
</ul>
</td>
<?php if($w == 7): ?>
</tr><tr>
<?php endif; ?>
<?php endforeach; ?>
<?php if($end != 7): ?>
<td colspan="<?php echo 7-$end; ?>" class="padding"></td>
<?php endif; ?>
</tr>
</tbody>
</table>
</div>
<?php endforeach; ?>
</div>
<div class="clear"></div>
Ma page date.php :
<?php
class Date{
var $days = array('Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche');
var $months = array('Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre');
function getEvents($year){
global $DB;
$req = $DB->query('SELECT id, dispo, statut,date FROM calendrier WHERE YEAR(date)='.$year.' AND dispo = 1');
$r = array();
while($d = $req->fetch(PDO::FETCH_OBJ)){
$r[strtotime($d->date)]$d->id] = $d->statut;
}
return $r;
}
function getAll($year){
$r = array();
$date = new DateTime($year.'-01-01');
while($date->format('Y') <= $year){
//Ce que je veux => $r[ANNEE][MOIS][JOUR] = JOUR DE LA SEMAINE
$y = $date->format('Y');
$m = $date->format('n');
$d = $date->format('j');
$w = str_replace('0', '7', $date->format('w'));
$r$y]$m]$d] = $w;
$date->add(new DateInterval('P1D'));
}
return $r;
}
}
Mon formulaire d'insertion :
<form action="../admin/liste_reservation.php" method="post">
<label for="datedebut">Date de début du Séjour :</label>
<input type="date" name="datedebut" id="datedebut" value="<?php echo $datedebut; ?>" class="form-control" style="width:40%;"><br />
<label for="datefin">Date de fin du Séjour :</label>
<input type="date" name="datefin" id="datefin" value="<?php echo $datefin; ?>" class="form-control" style="width:40%;"><br />
<br>
<input type="hidden" name="id_news" value="<?php echo $id_reservation; ?>" />
<button type="submit" value="Envoyer" class="btn btn-success btn-small">Envoyer</button>
</form>
Le traitement du formulaire :
if (isset($_POST'datedebut']) AND isset($_POST'datefin']))
{
$datedebut = addslashes($_POST'datedebut']);
$datefin = addslashes($_POST'datefin']);
// On vérifie si c'est une modification de news ou non.
if ($_POST'id_reservation'] == 0)
{
global $DB;
$req = $DB->query("INSERT INTO calendrier(id, datedebut, datefin, dispo, statut) VALUES('', '" . $datedebut . "', '" . $datefin . "', 1, 'Réservé')");
// Ce n'est pas une modification, on crée une nouvelle entrée dans la table.
}
else
{
// On protège la variable "id_reservation" pour éviter une faille SQL.
$_POST'id_reservation'] = addslashes($_POST'id_reservation']);
// C'est une modification, on met juste à jour les dates.
global $DB;
$req = $DB->query("UPDATE calendrier SET datedebut='" . $datedebut . "', datefin='" . $datefin . "' WHERE id='" . $_POST'id_reservation'] . "'");
}
}
Dans ce cas la, comme je l'ai expliqué :
Tu associes tes événement a un jour du calendrier
function getEvents($year){
global $DB;
$req = $DB->query('SELECT id, title, datedebut, datefin FROM calendrier WHERE YEAR(date)='.$year); // Recuperation des evenements
$r = array();
while($d = $req->fetch(PDO::FETCH_OBJ)){ // Pour chaque evenement recupere depuis la base
$debut = strtotime($d->datedebut); // On recupere la date de debut de la plage
$fin = strtotime($d->datefin); // On recupere la date de fin de la plage
$cursor = $debut; // On cree un curseur qui passera pas tous les jours de l'evenement
while ($cursor <= $fin) { // On parcourt tous les jours de la plage de l'evenement
$r$cursor]$d->id] = $d->statut; // On ajout a la journee actuelle l'evenement
$cursor += 86400; // On ajoute un journee pour passer au jour suivant
}
}
return $r;
}
Chaque événement est alors dispatché sur tous les jours qui le compose.
Je ne vois pas comment être plus précis (déjà que je n'aime pas donner du code .....), et espère avoir été assez clair pour que tu comprennes l'idée.
Azerus
Bonjour,
Si j'ai bien compris, tu sais comment le stocker, mais pas comment l'utiliser après ?
Si oui, alors je te conseillerais de le faire en ajoutant une partie javascript pour ajouter les plages à ton calendrier.
Je pense qu'il s'agit de la façon la plus simple de gérer ton problème.
Je ne peux pas être plus précis sur l'affichage des différentes plages dans ton calendriers, car cela dépend du rendu que tu veux avoir.
J'espère avoir répondu à tes questions.
Azerus
Bonjour Azerus,
Merci de ta réponse. Cependant, je ne suis déjà pas forcément une flèche en PHP (bien que je me débrouille un minimum) mais en JavaScript.. c'est même pas la peine.
Le soucis c'est qu'en fait, pour une date fixe, sa fonctionne très bien, mais je voudrais faire le même système avec une plage de date.
Autre proposition :
Après récupération de tes evenements, tu les parcours pour créé le tableau de cache que tu fait actuellement :
Pour chaque jour de la plage de l'evenement, tu rajoutes l'évènement à la journée.
L'inconvénient est que tu ne pourras pas visuellement et simplement voir qu'un evenement est sur plusieurs jours ou non.
L'avantage est que c'est beaucoup plus simple ^^
Azerus
Je vais tâcher d'être plus claire (désolé, c'est pas forcément facile d'expliquer son besoin ^^")
Prenons la démonstration du calendrier proposé par GrafikArt : http://www.grafikart.fr/demo/PHP/calendar/index.html
On voit sur le calendrier, des puces, puces qui servent à marquer un événement.
L'affichage de ses événements se fait par le biais d'une lecture dans la bdd.
Un enregistrement se fait de la sorte suivante : ID, TITLE, DATE
Donc chaque événements est caractérisés par une et une seule DATE.
Un événement est marqué dans le calendrier comme suit :
function getEvents($year){
global $DB;
$req = $DB->query('SELECT id, title, date FROM calendrier WHERE YEAR(date)='.$year);
$r = array();
while($d = $req->fetch(PDO::FETCH_OBJ)){
$r[strtotime($d->date)]$d->id] = $d->statut;
}
return $r;
}
--------------------------------------------------------------------------------------------
<ul class="events">
<?php if(isset($events$time])): foreach($events$time] as $e): ?>
<li><?php echo $e; ?></li>
<?php endforeach; endif; ?>
</ul>
Moi je voudrais qu'un événement se caractérise par un ensemble de DATE (datedebut et datefin par exemple).
Si datedebut = 01012014 et datefin = 14012014, je voudrais que les 14 jours soient marqués d'une puce.
Le formulaire, l'insertion et la lecture dans la base de données n'est pas un problème, ce que je cherche à faire, c'est comment les afficher.
Voilà, en espérant avoir été plus claire,
Merci d'avance, et merci de votre patience
Bonjour Azerus,
ton code fonctionne parfaitement, je te remercie beaucoup !
J'avais déjà du mal avec la POO, mais la notion de curseur en MySQL m'était inconnue jusqu'à ce jour.
Quel dommage que cette notion ne soit pas abordée en cours d'SQL lorsque j'étais à la Fac...
Je dormirais désormais moins bête !
Merci encore !
Juste pour indication, ce n'est pas un curseur en MySQL, c'est juste une variable PHP.
Je l'appelle $cursor car elle indique à quelle date on est dans une boucle.
Grosso modo, c'est comme une barre de chargement :
0% ====> ] 40%
0% = date de debut
100% = date de fin
40% = curseur, par exemple, je suis au 4eme jour sur 10 de l'evenement.
J'espere avoir ete plus clair.
Azerus