BLOG

Geburtstage mit dem Calendar View anzeigen

Neben Standard-Ereignissen, die einen festen Start und ein festes Ende haben, will man in seinem Kalender vielleicht auch Geburtstage und zum Beispiel Jahrestage anzeigen. Dies könnte man mit der Date-Repeat API erreichen, was aber bedeutet, dass man die jährliche Wiederholung für jedes Datumsfeld über ein nicht gerade unkompliziertes Formular jedes Mal erneut einstellen muss. Und funktioniert hat das in meinen Tests auch nicht zuverlässig.
Von daher ist die Antwort auf die Frage, ob Geburtstage mit Date funktionieren, einfach nein. Das Date-Modul unterstützt keine Felder, die kein Jahr benutzen, und damit sind sie unmöglich in den Kalender zu bekommen. Es gibt auch keinen Weg, den View umzubiegen, sodass dies vielleicht doch gehen kann. Ich habe aber einen Weg gefunden, wie man den Kalender doch mit beliebigen Ereignissen füllen kann.

Warum es nicht geht

Date verwendet ein auf ISO basierendes Datum und ein solches muss vollständig sein. Wenn ich ein Jahr "2010" eingebe, wird der interne Wert immer "2010-01-01 00:00:00" sein.
Selbst wenn Date einen Patch erhält, der ermöglichen würde, ein Datum von beliebiger Granularität einzupflegen, und Date uns nur die entsprechenden Teile des Datums lieferte, würde das Calendar-Modul im SQL noch immer nur Ereignisse abfragen, die zwischen 01.01.2010 und 01.02.2010 liegen. In der Abfrage ist das Datum einfach fest eingebaut.

Lösung

Nach vielem Suchen habe ich eine Funktion hook_calendar_add_items() gefunden. Das Calendar-Modul ist leider völlig undokumentiert, woraus ich lerne, in einem Modul immer erst danach zu suchen, welche Hooks ich zur Verfügung habe. Wer jetzt denkt, dass damit das Problem ein Ende findet, der irrt sich leider. Der Hook selbst sieht so aus:

<?php
 
// Merge in items from other sources.
 
foreach (module_implements('calendar_add_items') as $module) {
   
$function = $module .'_calendar_add_items';
    if (
function_exists($function)) {
      if (
$feeds = $function($view)) {
        foreach (
$feeds as $feed) {
         
$items = $feed;
        }
      }
    }
  }
?>

Und leider wird $items = $feed; gesetzt, was bedeutet, dass wir alle vorhandenen Informationen verlieren.
Also habe ich einen Calendar Modul Patch geschrieben. Ich habe aber nicht viel Hoffnung, dass der Patch schnell durchkommt.
<?php
 
// Merge in items from other sources.
 
foreach (module_implements('calendar_add_items') as $module) {
   
$function = $module .'_calendar_add_items';
    if (
function_exists($function)) {
      if (
$feeds = $function($view)) {
        foreach (
$feeds as $feed) {
         
$function($view, $items);
        }
      }
    }
  }
?>

Der Unterschied hierbei ist, dass wir das Views-Objekt und das $items-Array übergeben bekommen. Nun können wir Folgendes machen:
<?php
/*
* Implementation of hook_calendar_add_items().
*/
function cp_birthday_calendar_add_items($view, &$items) {
 
$date = date_make_date('now');

 
$node = new stdClass();
 
$node->node_title = '123456';
 
$node->calendar_start_date = $date;
 
$node->calendar_end_date = $date;
 
$items[] = $node;
}
?>

Da wir &$items nun referenzieren, können wir auf dem Array arbeiten. Die von mir angegebenen Daten sind das Minimum, das man braucht, um einen Event in den Kalender zu bringen. Aber Vorsicht! Ich habe lange mit einem Debugger an der Sache gesessen. Zum einen fehlen hier diverse Felder und PHP wird Warnungen ausgeben. Zum anderen ist es wirklich wichtig, dass ihr die Views-Feldnamen benutzt! $node->title; wird nicht funktionieren. $node->node_title; ist der Name des Views-Feldes. Es reicht also nicht, einen Node zu laden. Man muss eine Übersetzung in die Views Felder machen.

Wenn ihr also den Patch benutzt und euch durch die Benamung kämpft, dann steht Geburtstagen nichts mehr im Wege.

Kommentare

HiDu kannst dir dir dafür mal

Hi

Du kannst dir dir dafür mal die Date Repeat API anschauen. Wenn es sich um spezielle Events handelt, kann das doch eine Lösung sein.

Ansonsten ist das oben beschriebene eine neutrale Lösung. Ich kann mir vorstellen, das man CCK Felder anlegt, welche die Daten abspeichern und dann über ein spezielles Modul, das dann die gewünschten Regeln beachtet in den Kalender bringt. Ich denke das mehr als 2 Tage arbeit.

Könnte man auch ein php

Könnte man auch ein php script schreiben welches folgendnes kann:
-wöchentlich wiederholende termine ( jeden freitag um 19 uhr)
-jede zweite woche im monat das selbe Ereignis

und ist es dann immer noch möglich einen durch das script erzeugte termin zu löschen bzw. mit einem anderen (ausnahmetermin) zu überschreiben.

Vermutlich ist, das wesentlich komplexer und würde daher viel zeit zum umsetzen brauchen. oder?
Ich selbst habe leider keine php kenntnisse und würde mich daher über eine fachkundige meinung sehr freuen.

Hans

Kommentar hinzufügen

Der Inhalt dieses Feldes wird nicht öffentlich zugänglich angezeigt.
Mit dem Absenden dieses Formulars, akzeptieren Sie die Datenschutzrichtlinie von Mollom.