Calendrier en PHP

Après avoir un peu cherché un petit calendrier PHP facilement paramétrable, comme je n'ai rien trouvé qui me convenait, j'ai décidé de m'en faire un moi-même [Edit: il faut dire que c'était au siècle dernier...]. Le code source complet se trouve à la fin de cette page, mais avant, quelques explications sur son utilisation.

Un simple calendrier

Septembre 2017
LMMJVSD
    123
45678910
11121314151617
18192021222324
252627282930 

La fonction pour créer le calendrier d'un mois donné est~:

<?php Calendrier($mois$annee$liens); ?>

avec :

  • $mois : le numéro du mois entre 1 et 12,
  • $annee : le numéro de l'année sur 4 chiffres (ex : 2006),
  • $liens : un tableau dont nous verrons l'utilité plus loin. Pour un usage de base, il suffit de passer un tableau vide.
Ci-contre, par exemple, le calendrier de ce mois-ci généré ainsi :
<?php $links=array(); Calendrier(092017$links); ?>

Paramétrer le style

Pour que ça soit plus joli, on peut définir quelques paramètres pour le style. Voilà les propriétés CSS utilisées pour le calendrier ci-dessus :

/* Feuille de style pour Calendrier */
table.cal { font-size:12px; background:#416DFF; border: 3px groove #0026A7; }
/* la case contenant le nom du mois */
.cal td.cal_titre { font-weight:bold; }
/* les cases des jours de la semaine */
.cal th { text-align:center; background:#0026A7; color:#DAE2FF; }
/* les autres cases */
.cal td { text-align:center; background:#DAE2FF; margin:0px; padding:0px; }
/* la case correspondant à aujourd'hui */
.cal td.today { border: 2px solid fuchsia; margin:0; padding:-2px; }

mais on peut bien sûr paramétrer à son goût, tout ceci étant évidemment optionnel...

Ajouter des liens

On a vu que le troisième paramètre de la fonction Calendrier est un tableau. Celui-ci peut donner le contenu de la case correspondant à certains jours. Il s'agit du texte qui sera mis entre les balises <td> et </td>. S'il n'y a rien dans $links[j], on affiche simplement le numéro du jour, c'est-à-dire j.

$links[0] permet de remplacer le titre du calendrier du mois. Comme on l'a vu plus haut, on affiche le nom du mois et l'année par défaut.

Le code suivant permet par exemple de créer le calendrier du mois de mai 2006 ci-contre :

le joli mois de mai 2006
LMMJVSD
1234567
891011X1314
15161718192021
22232425262728
293031    
<?php 
     $links
=array();
     
$links[0] = 'le joli mois de mai 2006';
     
$links[1] = '<a href="fichier1.html">1</a>';
     
$links[5] = '<a href="fichier5.html" class="st1">5</a>';
     
$links[12] = '<span class="st2">12</span>';
     
Calendrier(52006$links);
  
?>

Le style par défaut des liens et les nouveaux styles st1 et st2 peuvent être également paramétrés à l'aide de propriétés CSS.

Voilà par exemple le style utilisé ci-contre :

/* les cases avec un lien */
.cal td a { background:#fff; display:block; text-decoration:none; font-weight:bold; }
/* un premier style */
.cal .st1 { font-weight:bold; background:Turquoise; }
/* un second style */
.cal .st2 { font-weight:bold; color:Purple; }

Exemple d'utilisation

J'utilise par exemple ce calendrier pour marquer mes dates de réunion, et faire un lien vers le compte rendu (oui, je sais, j'ai de la chance : je n'ai pas plus d'une réunion par jour...). Comme je suis très feignante, je me suis encore simplifié la vie avec la fonction suivante :

<?php
  
function Lien($day,$month,$year,$class) {
    
$NomDuMois=array("erreur","Janvier","Fevrier","Mars","Avril","Mai","Juin",
                 
"Juillet","Aout","Septembre","Octobre","Novembre","Decembre");
    
$monthname=$NomDuMois[$month+0];
    
$filename 'reunions'.$monthname.$year.'.php';
    if (
$day == 0)
      
$lien='<a href="'.$filename.'">'.$monthname.' '.$year.'</a>';
    else
      
$lien='<a href="'.$filename.'#j'.$day.'" class="'.$class.'">'.$day.'</a>';
    return 
$lien;
    }
?>

Elle construit un lien vers un fichier reunionsMoisAnnee.php, et plus précisément vers l'ancre #jJour si le numéro du jour demandé est différent de 0.

Il me suffit ensuite d'indiquer les dates de réunions, en précisant le type. Chaque type correspond à un style que l'on peut définir dans le CSS. Dans l'exemple suivante, on utilise deux types de réunions contrat et interne.

<?php
function Exemple () {
  
$lesannees=array();

  
$lesmois=array();  //=== tableau des mois de 2006

  
$jours=array(); $mois 11// réunions de Novembre 2006
  
$jours[16] = 'contrat'$jours[30] = 'interne';
  
$lesmois[$mois] = $jours;

  
$jours=array(); $mois 12// réunions de Decembre 2006
  
$jours[5] = 'interne';
  
$lesmois[$mois] = $jours;

  
$lesannees[2006] = $lesmois;

  
$lesmois=array();  //=== tableau des mois de 2007

  
$jours=array(); $mois 1// réunions de Janvier 2007
  
$jours[9] = 'contrat'$jours[16] = 'interne';
  
$lesmois[$mois] = $jours;

  
$lesannees[2007] = $lesmois;

  return 
$lesannees;
}
?>

Une petite boucle permet enfin de générer les calendriers correspondant au contenu du tableau $lesannees :

<?php
  
function Boucle ($lesannees) {
  foreach(
$lesannees as $a=>$lesmoisa) {
    foreach(
$lesmoisa as $m=>$reunions) {
      
$links=array();
      
$links[0] = Lien(0$m$a'');
      foreach(
$reunions as $j=>$lieu)
        
$links[$j] = Lien($j$m$a,$lieu);
      echo 
'<div class="cal">';
      
Calendrier($m,$a,$links);
      echo 
'</div>';
      }
    }
  }
?>

Et voilà le résultat pour l'exemple ci-dessus généré simplement par :

<?php Boucle (Exemple ()); ?>
Novembre 2006
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
27282930   
Decembre 2006
LMMJVSD
    123
45678910
11121314151617
18192021222324
25262728293031
Janvier 2007
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Bon, dans l'exemple, les liens ne sont pas branchés, car il faut quand même au bout du compte écrire les comptes-rendu dans les fichiers reunionsMoisAnnee.php... rien n'est parfait !

Le code source

Pour finir, voilà le code PHP de la fonction Calendrier avec quelques explications en commentaire :

<?php
function Calendrier($month,$year,$links) {

  
$MonthNames = array(=> "Janvier","Fevrier","Mars","Avril","Mai","Juin",
               
"Juillet","Aout","Septembre","Octobre","Novembre","Decembre");
  
$monthname $MonthNames[$month+0];

  
// on ouvre la table
  
echo '<table class="cal" cellspacing="1">';

  
// Première ligne = mois et année ou link[0]
  
$title array_key_exists(0$links) ? $links[0] : $monthname.' '.$year;
  echo 
'<tr><td colspan="7" class="cal_titre">'.$title.'</td>'."</tr>\n";

  
// Seconde lignes = initiales des jours de la semaine
  
$DayNames = array("L","M","M","J","V","S","D");
  echo 
'<tr>'; foreach ($DayNames as $d) echo '<th>'.$d.'</th>'; echo "</tr>\n";

  
// On regarde si aujourd'hui est dans ce mois pour mettre un style particulier
  
if ($year == date('Y') && $month == date('m'))
    
$today date('d');
  else
    
$today 0;

  
$time mktime(0,0,0,$month,1,$year); // timestamp du 1er du mois demandé
  
$days_in_month date('t',$time);     // nombre de jours dans le mois
  
$firstday date('w',$time);          // jour de la semaine du 1er du mois
  
if ($firstday == 0$firstday 7;    // attention, en php, dimanche = 0

  
$daycode 1// ($daycode % 7) va nous indiquer le jour de la semaine.
                // on commence par le lundi, c'est-à-dire 1.

  // on ouvre une première ligne pour le calendrier proprement dit :
  
echo '<tr>';

  
// on met des cases blanches jusqu'à la veille du 1er du mois :
  
for ( ; $daycode<$firstday$daycode++) echo '<td>&nbsp;</td>';

  
// boucle sur tous les jours du mois :
  
for ($numday 1$numday <= $days_in_month$numday++, $daycode++) {
    
// si on en est au lundi (sauf le 1er), 
    // on ferme la ligne précédente et on en ouvre une nouvelle 
    
if ($daycode%== && $numday != 1) echo "</tr>\n".'<tr>';
    
// on ouvre la case (avec un style particulier s'il s'agit d'aujourd'hui)
    
echo ($numday == $today '<td class="today">' '<td>');
    
// on affiche le numéro du jour ou le contenu donné par l'utilisateur
    
echo (array_key_exists($numday$links) ? $links[$numday] : $numday);
    
// on ferme la case
    
echo '</td>';
    }

  
// on met des cases blanches pour completer la dernière semaine si besoin :
  
for ( ; $daycode%!= 1$daycode++) echo '<td>&nbsp;</td>';

  
// on ferme la dernière ligne, et la table.
  
echo '</tr>'; echo "</table>\n\n";
  }
?>

Exemples d'utilisation

Merci de me signaler vos utilisations. Je peux, si vous le souhaitez, ajouter un lien vers vos pages pour montrer d'autres exemples.

E-mail: Anne dot Pacalet at free dot fr

Valid XHTML 1.0 Strict Valid CSS! logo Vim