Génération automatique d’un calendrier avec SimpleCalendarComponent

Nous souhaiterions agrémenter notre application CakePHP d’un calendrier, pour présenter agréablement des données par ordre chronologique. Nous allons utiliser la classe SimpleCalendar et le composant SimpleCalendarComponent.

1. Présentation de la classe SimpleCalendar

La classe SimpleCalendar permet de générer un calendrier au balisage valide (x)HTML 1.0 Strict, de manière simple et efficace.

Voici quelques exemples d’utilisation :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$cal = new SimpleCalendar();
 
// afficher le calendrier du mois et de l'année courante
$cal->showCalendar();
 
// avancer le calendrier vers le mois prochain
$cal->toNextMonth();
 
// ré-affichage du calendrier
$cal->showCalendar();
 
// recule le calendrier d'un an
$cal->toDate('previous year');
 
// ré-affichage du calendrier
$cal->showCalendar();
 
// on souhaite afficher le calendrier de septembre 2008 en anglais avec l'affichage du nom complet des jours :
$cal = new SimpleCalendar('09', '2008', array('locale' =>; 'en', 'fullDayName' => true));

Nous souhaitons à présent intégrer le calendrier dans notre application CakePHP, et rendre cliquables certaines dates en fonctions de nos données.

2. Installation de la classe et du composant

Nous devons dans un premier temps télécharger la classe SimpleCalendar et la placer dans le répertoire vendors/calendar de notre application. Après installation, nous obtenons le chemin suivant : {app}/vendors/calendar/simple_calendar.php

Il faut à présent intégrer la classe SimpleCalendar au sein de notre application, pour cela, nous allons installer le composant spécialement créé à l’occasion : SimpleCalendarComponent. Celui-ci va charger et instancier la classe SimpleCalendar au sein l’application, à l’aide de la fonction vendor.

3. Usage simple

Imaginons la gestion d’un blog avec des articles (posts) et des commentaires (comments).

Soit les données du modèle suivant :

Post hasMany Comments Comments belongsTo Post

Nous souhaitons afficher notre calendrier sur la page de liste des articles (/posts/index) afin de mettre en évidence leur date de publication.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// {app}/controllers/post_controller.php
class PostsController extends AppController
{
  var $name = 'Posts';
 
  var $scaffold;
 
  // chargement du component
  var $components = array('SimpleCalendar');
 
  function index()
  {
    // récupération de la liste des articles
    $posts = $this->Post->find('all');
    $this->set('posts', $posts);
 
    // initialisation du composant
    $this->set('cal', $this->SimpleCalendar->setUp());
  }
}

Nous avons créé une variable $cal, à l’aide de la fonction Controller::set contenant une instance de la classe SimpleCalendar. Il ne reste plus qu’a afficher le calendrier dans notre vue.

1
2
// {app}/views/posts/index.ctp
$cal->showCalendar();

Le calendrier du mois en cours s’affiche. Libre à nous de mettre ce dernier en forme à l’aide de CSS :

Exemple de calendrier mis en forme

4. Usage avancé

Nous souhaitons à présent mettre en évidence des dates qui nous intéressent, par exemple la date de création d’un article, et faire de cette date un lien vers l’article.

Reprenons notre Contrôleur et modifions les paramètres d’appel de la fonction setUp() du SimpleCalendarComponent.

1
2
3
4
5
6
7
8
9
10
11
// {app}/controllers/posts_controller.php
function index()
{
  // récupération de la liste des articles
  $posts = $this->Post->find('all');
  $this->set('posts', $posts);
 
  $this->set('cal', $this->SimpleCalendar->setUp(
    null, null, array('activeLinks' => array('links' => $posts))
   ));
}

Et voilà ! Comme par magie, nos liens pointent vers l’action view du Contrôleur PostsController avec l’id du post associé : /posts/view/{$post['Post']['id']}.

Nous souhaitons à présent afficher non plus la date de création, mais la date de publication des articles (supposons un champ published dans la table posts). Nous souhaitons d’autre part appeler nos articles par leur date de publication et leur titre : /posts/03/2007/my-first-post.

1
2
3
4
5
6
7
$this->set('cal', $this->SimpleCalendar->setUp(
  null, null, array('activeLinks' => array(
    'links' => $posts,
    'path' => 'posts' . DS . date('m') . DS . date('Y'),
    'identifier' => 'title',
    'datefield' => 'published'))
 ));

Pour notre dernier exemple, nous ne souhaitons non plus afficher les dates relatives aux articles mais les dates associées aux commentaire des articles.

1
2
3
4
5
6
7
8
9
10
function index()
{
  $posts = $this->Post->find('all');
  $this->set('posts', $posts);
 
  $comments = Set::extract($posts, '{n}.Comment');
  $this->set('cal', $this->SimpleCalendar->setUp(
    null, null, array('activeLinks' => array('links' => $comments, 'path' => 'comments/view'))
  ));
}

Quelques précisions :

  • Par défault, les liens actifs $activeLinks utiliseront le modèle en index 0 de la collection d’objet du paramètre links (ce qui conviendra dans la majorité des cas) ;
  • Le lien généré pointera par défaut sur l’action view du Contrôleur concerné, il est cependant possible de modifier celui-ci, voir les exemples précédent ;
  • Si le paramètre datefield de $activeLinks n’est pas précisé, le champs date par défaut sera automatiquement created ;
  • La classe et le composant ne sont pas en version finale, il se peut que des bugs subsistent ;
  • Sur les systèmes *nix, vous pouvez obtenir la liste des locales disponibles à l’aide de la commande locale -a.
Télécharger SimpleCalendar et SimpleCalendarComponent (fichier zip, 4,27 Ko)

Christophe Cholot

Commentaires

Merci pour ce super blog très riche en information. Je rencontre cependant des difficultés dans l’utilisation de SimpleCalendar. Il me semble tout avoir bien installé (fichiers copiés au bon endroit): je n’ai aucun message d’erreur de cakephp (v.1.2), mais déjà le point 3 « Usage simple » ne fonctionne pas… j’ai juste l’en-tête du calendrier avec la date et les jours de la semaine, ensuite une ligne de 7 « td » avec une classe « disabled ».

Pour faire plus simple, voici le résultat:

13 February 2007

MonTueWed ThuFriSatSun

Merci d’avance pour votre aide.

Guillaume

Merci tout d’abord de ton intérêt pour ce composant. Il y a en effet un problème sur les systèmes Windows lors de l’utilisation de la fonction strftime avec le paramètre %u. La solution est de remplacer la ligne 214 du fichier app/vendors/calendar/simple_calendar : $weekDay = strftime(‘%u’, $tstamp); par $weekDay = strftime(‘%w’, $tstamp) == 0 ? 7 : strftime(‘%w’, $tstamp);

Je mets à jour l’archive avec cette correction dès que possible.

Réponse rapide et efficace! Ce composant est très intéressant et très utile, ainsi que toutes les informations disponibles sur ce site. Merci beaucoup.

Bonsoir, j’ai installé ce composant GE-ANT :)

mais il y a une coquille il faudrait ligne 56 du Component : if(isset($options['activeLinks']) && sizeof($options['activeLinks']) > 1){ à la place de if(isset($options['activeLinks']) && sizeof($options['activeLinks']) > 0){

ceci pour eviter un warning ligne 62 quand $options['activeLinks'] est vide le sizeof($options['activeLinks']) d’un array « vide » retourne 1 :/

cdt.

Hello,

Merci de ton intêret pour ce composant et cette correction. Je travail actuellement sur la prochaine version du composant qui inclura une vue par jour/semaine/mois, une surcouche en ajax, des tests unitaires .. :)

Bonsoir, une feature request (pour abuser;) : possibilité d’avoir une vue avec 3 calendriers de rang : le mois précédent – l’encours – le suivant exemple : http://www.dafunspirit.net/calendar/ si non, j’utiliserai SimpleCalendar pour afficher que les evenements d’un plugin (ce qui en soit est impecc’ !) et finirai ma conversion du module calendar sur mon puncake comme afficher ci dessus. cdt.

Bonjour, un petit bug qd je suis sur mon url http://localhost.cakephp/articles/index

le lien vers un de mes « evenements » est : http://localhost.cakephp/articles/articles/view/test-capricieux

j’ai un « doublon » dans mon url du coup je me vois contrains de faire

‘path’ => ‘/articles/view’

alors que si demain l’url rewritting est off ; ce lien ne menera plus nulle part :/

cdt.

j’oubliais un autre détail si on a plusieurs evenements ; seul le dernier est lié dans le calendrier.

Bonjour, J’ai installé le composant SimpleCalendar dans mon application, mais je suis confronté à deux problème :

1 – j’arrive pas à obtenir de lien cliquable au niveau des jour du calendrier 2 – je n’arrive pas à avoir le libellé des jours en français voici l’appelle au calendrier dans mon code : $this->set(‘cal’, $this->SimpleCalendar->setUp(null, null, array(‘locale’ => ‘fr_FR’, ‘activeLinks’ => array(‘links’ => $activité,’path’ => ’sites/show/’))));

Est ce que quelqu’un peut m’aider à en venir à bout ?

merci pour ces articles tres intéressant, je ne comprend pas comment j’ai pu utiliser cake plusieurs semaines avant de trouver ce site… je me permet de suggérer une mise a jour car chez moi (cake_1.2.0.7692-rc3) la fonction vendor n’existe pas (plus?) après un coup d’oeil a l’api cake je m’apperçois qu’elle est obsolete et remplacé par la fonction: App::import donc avec les nouvelle version de cake:

remplacer la ligne 40 du composant simple calendar: vendor(‘calendar/simplecalendar’); par: App::import(‘Vendor’, array(‘calendar’.DS.’simplecalendar’));

encore bravo et merci

complement du commentaire précedent:

attention au copier coller:

‘Vendor’ ‘calendar’ et ’simple_calendar’ sont des strings et pas des constantes

Merci pour ce petit composant bien utile, j’aurai une petite question de débutant:

comment faire pour afficher (et naviguer) vers mois précédent, mois suivant un peu comme dans un datepicker?

Très très bon composant qui me convient à merveille. J’ai cependant repéré un petit bug, grâce au mois de juin… le premier jour du mois est un lundi Dans la fonction _getWeeks, on incrémente la semaine si le modulo de weekDay est 1

$weekCount =  $weekDay % 7 == 1 ? ++$weekCount : $weekCount;

Si le premier jour du mois est un lundi , 1 % 7 = 1 et donc weekCount est incrémenté : la ligne 1 du tableau des semaines est vide, et la première semaine se retrouve en ligne 2

Pour résoudre ça, j’ai fait ceçi :

$weekCount =  ($weekDay % 7 == 1 && $dayNumber!=1)  ? ++$weekCount : $weekCount;

Il y a peut être mieux comme correction, mais ça à l’air de fonctionner.

Bonjour et merci pour cet outil. j ai fait exactement comme indiqué et j’ai même corrigé le code $weekDay =.. comme tu as corrigé Guillaume ..mais j ai un problemè c’est que je ne vois rien. je vois tous le tableau dans les source code en Firefox et IE mais rien n apparait comme sur le site. Pouvez vous me dire ce que j’ ai mal fait ? je suppose qu il me manque un fichier css!

Bonjour,

Merci pour ce tuto

Mon souci se site dans le fait que par exemple pour aujourd’hui, il me dit qu’on est le 7eme jour de la semaine alors qu’on est le 6eme.

Exemple : http://www.cwx.be/wesb/

quelqu’un a-t-il trouvé comment changer de mois en cliquant sur un lien ?

Je cherche moi aussi à passer aux mois suivants avec un lien est-ce possible ?

Participez

Pour insérer une portion de code, utilisez <pre lang="php">...</pre>