Voici une proposition qui d'abord repose sur SQL pour préparer des critères de classement par id événement et par date début. Comme ça on pourra dire avoir des ruptures de lots pour tel événement, et pour tant de dates par événement.
Voici donc la requête:
$sql = "SELECT
e.id_evenement as id,
e.description as descri,
e.ville as ville,
e.codepostal as cp,
d.date_debut as dated,
d.date_fin as datef
FROM
evenements AS e
join
dates AS d
on d.id_evenement = e.id_evenement
ORDER BY
e.id_evenement, d.date_debut ASC";
En suite, c'est au rôle de PHP de classer dans un Array, les enregistrements reçus de SQL dument triés dans l'ordre de classement voulu. On peut utiliser pour ça un tableau associatif dont les index sont nommés par les critères de classement choisis dans SQL à savoir : id événement, et la date de début. Seulement on va décortiquer cette date en année, mois et jour pour regrouper les mêmes événements dans une seule case id, pour la mêmes année et le même mois et jour.
Voici comment créer un tel tableau à partir de la requête SQL:
$events = array();
while($resultats && $row = mysql_fetch_assoc($resultats))
{
//Classement des événements par années/mois/jour
extract($row);
$annee = (int)date('Y', strtotime($dated));
$mois = (int)date('m', strtotime($dated));
$jour = (int)date('d', strtotime($dated));
$events[$id][$annee][$mois][$jour][] = $row;
}
En fait, PHP ne fait que reprendre l'ordre de tri fourni par SQL, et spécifie les champs comme index hiérarchisés dans le tableau pour éviter le dédoublement des lignes correspondant à ces index.
Par exemple, si on a 3 événements concernant l'id 1 la requête retournera 3 fois l'id 1 dans les enregistrements. Mais puisque PHP enregistre l'id comme index du tableau, le même id ne sera stocké qu'une fois.
Le reste du programme consiste à lire le tableau produit par l'ordre hiérarchique établie : c'est à dire par id de l'événement, par année, par mois et par jour. Et ainsi l'on peut formuler la fameuse phrase que notre ami souhaite :
L'événement n° 1 aura lieu Les 11 et 13 Juin et le 15 Juillet 2009
Voici le programme général:
<?php
//Texte SQL
$sql = "SELECT
e.id_evenement as id,
e.description as descri,
e.ville as ville,
e.codepostal as cp,
d.date_debut as dated,
d.date_fin as datef
FROM
evenements AS e
join
dates AS d
on d.id_evenement = e.id_evenement
ORDER BY
e.id_evenement, d.date_debut ASC";
//Exec SQL
$resultats = mysql_db_query("test", $sql, mysql_connect("localhost", "root"));
//calendrier français
$mois_fr = array(1=>"Janvier", 2=>"Février", 3=>"Mars", 4=>"Avril", 5=>"Mai", 6=>"Juin",
7=>"Juillet", 8=>"Août", 9=>"Septembre", 10=>"Octobre", 11=>"Novembre", 12=>"Décembre");
//Boucle sur les résultats
$events = array();
while($resultats && $row = mysql_fetch_assoc($resultats))
{
//Classement des événements par années/mois/jour
extract($row);
$annee = (int)date('Y', strtotime($dated));
$mois = (int)date('m', strtotime($dated));
$jour = (int)date('d', strtotime($dated));
$events[$id][$annee][$mois][$jour][] = $row;
}
//Affichage
$event = "";
if (is_array($events) && count($events)>0)
{
//début des id event
foreach($events as $id=>$idArray)
{
//début des années du même id event
$event .= "L'événement $id aura lieu ";
$a=0;
foreach($idArray as $annee=>$anneesArray)
{
//début des mois de la même année
$m=0;
foreach($anneesArray as $mois=>$moisArray)
{
//début des jours du même mois
$event .= count($moisArray)<=1?" le ":" les "; //+ écrit "le" ou "les" selon le nombre de jours event du mois
$j=0;
foreach($moisArray as $jour=>$dataEvent)
{
$event .= " <a href='#' onclick='show(" . json_encode($dataEvent) . ")'>$jour</a>" . ($j<count($moisArray)-2?", ":" et "); //+ remplace dernier "," par "et"
$j++;
}
//fin des jours du même mois
$event = preg_replace('#(et)\s?$#i', ' ', $event); //+ remplace dernier "et" par " "
$event .= $mois_fr[$mois] . ($m<count($anneesArray)-2?", ":" et "); //+ remplace dernier "," par "et"
$m++;
}
//fin des mois de la même année
$event = preg_replace('#(et)\s?$#i', ' ', $event); //+ remplace dernier "et" par " "
$event .= " $annee" . ($a<count($idArray)-1?", ":" et "); //+ remplace dernier "," par "et"
$a++;
}
//fin des années pour le même id
$event = preg_replace('#(et)\s?$#i', ' ', $event); //+ remplace dernier "et" par " "
$event .= "<br />";
}
//fin des id event
}
//
echo $event!=null?$event:"Aucun événement !";
?>
<div id="afficheur" style="width:200; height:150; background-color:yellow; color:blue; font-family:arial; font-size:small;"></div>
<script type="text/javascript">
//Afficher les données d'un objet jSon Array
function show(eventDataArray)
{
var eventData = eventDataArray[0];
document.getElementById("afficheur").innerHTML = '<h5>Evénement n°' + eventData.id + '</h5><hr>';
document.getElementById("afficheur").innerHTML += '<p>Date: ' + eventData.dated + '</p>';
document.getElementById("afficheur").innerHTML += '<p>Description: ' + eventData.descri + '</p>';
}
</script>
En supplément et en guise de finition, le script contient aussi des instructions qui déterminent quand il faut placer une "virgule" ou un "et" dans les phrases générées et des liens hypertextes sur les jours pour afficher le détail de l'event dans un div.
Et voici la base de test:
Code : Tout sélectionner
--
-- Structure de la table `dates`
--
CREATE TABLE IF NOT EXISTS `dates` (
`id_date` int(10) unsigned NOT NULL auto_increment,
`id_evenement` int(10) unsigned NOT NULL,
`date_debut` datetime NOT NULL,
`date_fin` datetime NOT NULL,
PRIMARY KEY (`id_date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=13 ;
--
-- Contenu de la table `dates`
--
REPLACE INTO `dates` (`id_date`, `id_evenement`, `date_debut`, `date_fin`) VALUES
(1, 16, '2008-09-15 16:24:39', '0000-00-00 00:00:00'),
(2, 16, '2008-09-17 16:31:55', '0000-00-00 00:00:00'),
(3, 16, '2008-11-09 16:32:00', '0000-00-00 00:00:00'),
(4, 17, '2008-09-25 19:27:07', '0000-00-00 00:00:00'),
(5, 17, '2008-09-16 19:27:21', '0000-00-00 00:00:00'),
(6, 18, '2008-09-19 11:51:39', '2008-09-26 11:51:43'),
(7, 19, '2008-09-30 16:47:51', '0000-00-00 00:00:00'),
(8, 20, '1987-06-11 20:30:00', '0000-00-00 00:00:00'),
(9, 21, '1987-06-11 20:30:00', '0000-00-00 00:00:00'),
(10, 22, '2008-12-20 20:30:00', '0000-00-00 00:00:00'),
(11, 16, '2008-09-11 16:32:00', '0000-00-00 00:00:00'),
(12, 16, '2009-01-12 00:00:00', '0000-00-00 00:00:00'),
(13, 16, '2009-01-20 00:00:00', '0000-00-00 00:00:00'),
(14, 16, '2009-03-15 00:00:00', '0000-00-00 00:00:00');
-- --------------------------------------------------------
--
-- Structure de la table `evenements`
--
CREATE TABLE IF NOT EXISTS `evenements` (
`id_evenement` int(11) NOT NULL auto_increment,
`description` varchar(200) collate utf8_bin NOT NULL,
`codepostal` char(5) collate utf8_bin NOT NULL,
`ville` varchar(70) collate utf8_bin NOT NULL,
PRIMARY KEY (`id_evenement`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=23 ;
--
-- Contenu de la table `evenements`
--
REPLACE INTO `evenements` (`id_evenement`, `description`, `codepostal`, `ville`) VALUES
(16, 'spectacle', '38000', 'beaurepaire'),
(17, 'spectacle2', '26210', 'lens-lestang'),
(18, 'spectacle3', '38000', 'grenoble'),
(19, 'spectacle4', '69000', 'lyon'),
(20, 'essai', '38000', 'grenoble'),
(21, 'essai', '38000', 'grenoble'),
(22, 'test2', '38000', 'grenoble');