kalenderdatei ueberarbeitet, getEvents auf VObject von sabre.io umgestellt

This commit is contained in:
+++ 2022-11-26 15:08:50 +01:00
parent 4d08672148
commit 78b461609f
2 changed files with 243 additions and 435 deletions

View file

@ -14,13 +14,13 @@ BEGIN:VEVENT
SUMMARY:"Chaostreff" SUMMARY:"Chaostreff"
UID:0000000002@kraut.space UID:0000000002@kraut.space
CLASS:PUBLIC CLASS:PUBLIC
DESCRIPTION:"Offene Runde" DESCRIPTION:Offene Runde
DTEND;TZID=CET:20200623T235900 DTEND;TZID=CET:20200623T235900
DTSTAMP;TZID=CET:20200623T125900 DTSTAMP;TZID=CET:20200623T125900
DTSTART;TZID=CET:20200623T200000 DTSTART;TZID=CET:20200623T200000
GEO:50.9292035\,11.5825763 GEO:50.9292035\,11.5825763
LOCATION:"Krautgasse 26\, 07743 Jena" LOCATION:Krautgasse 26, 07743 Jena und online unter https://kraut.space/chaostreff
URL;VALUE="HTTPS://kraut.space/chaostreff" URL:https://wiki.kraut.space/hswiki:veranstaltungen:regelmaessige:chaostreff:start
ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:office@kraut.space ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:office@kraut.space
REFRESH-INTERVAL;VALUE=DURATION:P1W REFRESH-INTERVAL;VALUE=DURATION:P1W
RRULE:FREQ=WEEKLY RRULE:FREQ=WEEKLY
@ -29,28 +29,28 @@ BEGIN:VEVENT
SUMMARY:"Brettspielrunde" SUMMARY:"Brettspielrunde"
UID:0000000003@kraut.space UID:0000000003@kraut.space
CLASS:PUBLIC CLASS:PUBLIC
DESCRIPTION:"Brettspielerei" DESCRIPTION:Brettspielerei
DTEND;TZID=CET:20220518T235900 DTSTAMP;TZID=CET:20221116T125900
DTSTAMP;TZID=CET:20220518T125900 DTSTART;TZID=CET:20221116T200000
DTSTART;TZID=CET:20220518T200000 DTEND;TZID=CET:20221116T235900
GEO:50.9292035\,11.5825763 GEO:50.9292035\,11.5825763
LOCATION:"Krautgasse 26\, 07743 Jena" LOCATION:Krautgasse 26, 07743 Jena
URL;VALUE="HTTPS://kraut.space/brettspielerei" URL:https://wiki.kraut.space/hswiki:veranstaltungen:regelmaessige:brettspielerei
ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:office@kraut.space ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:office@kraut.space
REFRESH-INTERVAL;VALUE=DURATION:P1W REFRESH-INTERVAL;VALUE=DURATION:P1W
RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=MO;BYDAY=FR;BYWEEKNO=2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,36,38,40,42,44,46,48,50,52 RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=MO;BYDAY=WE;BYWEEKNO=2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,36,38,40,42,44,46,48,50,52
END:VEVENT END:VEVENT
BEGIN:VEVENT BEGIN:VEVENT
SUMMARY:"Linux User Group" SUMMARY:"Linux User Group"
UID:0000000004@kraut.space UID:0000000004@kraut.space
CLASS:PUBLIC CLASS:PUBLIC
DESCRIPTION:"Alles rund um Linux" DESCRIPTION:Alles rund um Linux
DTEND;TZID=CET:20200625T235900 DTEND;TZID=CET:20200625T235900
DTSTAMP;TZID=CET:20200623T125900 DTSTAMP;TZID=CET:20200623T125900
DTSTART;TZID=CET:20200625T200000 DTSTART;TZID=CET:20200625T200000
GEO:50.9292035\,11.5825763 GEO:50.9292035\,11.5825763
LOCATION:"Krautgasse 26\, 07743 Jena" LOCATION:Krautgasse 26, 07743 Jena und online unter https://kraut.space/lug
URL;VALUE="HTTPS://kraut.space/lug" URL:https://wiki.kraut.space/hswiki:veranstaltungen:regelmaessige:lug:start
ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:office@kraut.space ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:office@kraut.space
REFRESH-INTERVAL;VALUE=DURATION:P1W REFRESH-INTERVAL;VALUE=DURATION:P1W
RRULE:FREQ=WEEKLY RRULE:FREQ=WEEKLY
@ -59,13 +59,13 @@ BEGIN:VEVENT
SUMMARY:"Gaming am Freitag" SUMMARY:"Gaming am Freitag"
UID:0000000005@kraut.space UID:0000000005@kraut.space
CLASS:PUBLIC CLASS:PUBLIC
DESCRIPTION:"Der Stammtisch für Videospielkultur" DESCRIPTION:Der Stammtisch für Videospielkultur
DTEND;TZID=CET:20220527T235900 DTEND;TZID=CET:20220527T235900
DTSTAMP;TZID=CET:20220527T125900 DTSTAMP;TZID=CET:20220527T125900
DTSTART;TZID=CET:20220527T190000 DTSTART;TZID=CET:20220527T190000
GEO:50.9292035\,11.5825763 GEO:50.9292035\,11.5825763
LOCATION:"Krautgasse 26\, 07743 Jena" LOCATION:Krautgasse 26, 07743 Jena
URL;VALUE="HTTPS://kraut.space/gamingamfreitag" URL:https://wiki.kraut.space/hswiki:veranstaltungen:regelmaessige:gaming
ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:office@kraut.space ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:office@kraut.space
REFRESH-INTERVAL;VALUE=DURATION:P1W REFRESH-INTERVAL;VALUE=DURATION:P1W
RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=MO;BYDAY=FR;BYWEEKNO=1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53 RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=MO;BYDAY=FR;BYWEEKNO=1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53
@ -74,15 +74,15 @@ BEGIN:VEVENT
SUMMARY:"Kinderbasteln" SUMMARY:"Kinderbasteln"
UID:0000000006@kraut.space UID:0000000006@kraut.space
CLASS:PUBLIC CLASS:PUBLIC
DESCRIPTION:"Natur und Technik für Vor- und Grundschulkinder" DESCRIPTION:Natur und Technik für Vor- und Grundschulkinder
DTEND;TZID=CET:20220611T120000 DTEND;TZID=CET:20220611T120000
DTSTAMP;TZID=CET:20220611T100000 DTSTAMP;TZID=CET:20220611T100000
DTSTART;TZID=CET:20220611T100000 DTSTART;TZID=CET:20220611T100000
GEO:50.9292035\,11.5825763 GEO:50.9292035\,11.5825763
LOCATION:"Krautgasse 26\, 07743 Jena" LOCATION:Krautgasse 26, 07743 Jena
URL;VALUE="HTTPS://kraut.space/kinderbasteln" URL:https://wiki.kraut.space/hswiki:veranstaltungen:regelmaessige:kinderbasteln
ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:basteln@kraut.space ORGANIZER;CN="VORSTAND HACKSPACE JENA E.V.":MAILTO:basteln@kraut.space
REFRESH-INTERVAL;VALUE=DURATION:P1W REFRESH-INTERVAL;VALUE=DURATION:P1W
RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=MO;BYDAY=FR;BYWEEKNO=1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53 RRULE:WKST=MO;FREQ=WEEKLY;BYDAY=2SA,4SA
END:VEVENT END:VEVENT
END:VCALENDAR END:VCALENDAR

View file

@ -1,344 +1,192 @@
<?php <?php
/** /**
* Datei: getEvents.php * file: getEvents.php
* Autor: bernd@nr18.space * date: 20.11.2022
* Letze Änderung: 08.07.2020 * user: bernd@nr18.space
* Kurzbeschreibung:
* Enthält Funktionen zum Parsen und Ausgeben einer iCalendar Kalenderdatei.
* Die Bibliothek zum Parsen des iCalendarfiles stammt von ZContent.
* Der Quelltext liegt auf https://github.com/zcontent/icalendar. Da sie
* auf calendar.org verlinkt war, dachte ich eigentlich, daß sie gut wäre.
*/ */
require_once("../src/lib/zapcallib.php");
ini_set('log_errors', 1);
ini_set('error_log', '../log/events.log');
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING & ~E_DEPRECATED);
use Sabre\VObject;
include '/usr/share/php/Sabre/VObject/autoload.php';
define ("ICAL_FILE", "krautspace.ics");
function printEventList(): bool
{
/** /**
* Die Startfuktion für die Ausgabe der Termine als Liste in index.php. * Reads the content of the given ical file and creates with this string a
* Nach erfolgreicher initialisierung läuft die Funktion durch das Array * vcalendar object.
* der Events (ZCalNode´s vom Typ 'VEVENT') ruft für jedes Element erst *
* die Funktion zur Umwandlung in ein assoziatives Array und dann die * @return vCalendar object | null
* Ausgabefunktion auf. Gibt einen Boolean zurück.
*/ */
$events = initEvents(); function initCalendar(): ?object {
$helper = new ZDateHelper(); try {
date_default_timezone_set("UTC"); $data = file_get_contents(ICAL_FILE);
$vcalendar = VObject\Reader::read(
/** $data
* Startdatum für wiederkehrende Termine aktualisieren );
* return $vcalendar;
* @var ZCiCalNode $event } catch (Throwable $th) {
*/ error_log("Failed to read calendar file.");
foreach ($events as $event) error_log($th->getMessage(), 0);
{ return null;
/**
* @var ZCiCalDataNode $eventDTStart
*/
$eventDTStart = $event->data['DTSTART'];
/** @var string[] $eventDTStartValues */
$eventDTStartValues = $eventDTStart->value;
$event_start = $eventDTStartValues[0] ?? '';
$unix_start = $helper->fromiCaltoUnixDateTime($event_start);
$rrule = $event->data['RRULE']->value[0];
//todo rrule always set
if (EventIsPast($unix_start) === true AND isset ($rrule))
{
$new_unix = calculateNextStart($unix_start, $rrule);
$date = date('Ymd', $new_unix);
$time = date('His', $new_unix);
$connector = 'T';
$new_start = "{$date}{$connector}{$time}";
$event->data['DTSTART']->value[0] = $new_start;
}
} }
/**
* Eventliste nach Startdatum sortieren
*/
usort($events, 'compareEventStart');
/**
* Termine ausgeben
*/
foreach ($events as $event)
{
printListItem($event);
}
return true;
} }
function printListItem(ZCiCalNode $event): bool
/** /**
* Die Ausgabefunktion für die Ausgabe der Termine als Liste. Hier wird die * Grabs all VEVENTS from vCalendar object, append they to a list and
* Zeitangabe des iCal-Formates in Datum, Uhrzeit und Wochentag umgewandelt. * returns the list.
* Anschließend erfolgt die Ausgabe der einzelnen Teile. *
* @param vCalendar object
* @return list | null
*/ */
{ function grabEvents(object $vcalendar): ?array {
date_default_timezone_set("UTC"); $eventlist = [];
$helper = new ZDateHelper(); try {
foreach ($vcalendar->VEVENT as $event) {
$eventlist[] = $event;
}
} catch (Throwable $th) {
error_log("Failed to grab evens.");
error_log($th->getMessage(), 0);
return null;
}
return $eventlist;
}
/**
* Becomes an instance from recurrency rule iterator and an datetime object.
* Until the iterators date is in future, we call for the next date.
*
* @param iterator object
* @param datetime
* @return datetime | null
*/
function getNextDate(object $rriterator, DateTime $now): ?DateTime {
foreach ($rriterator as $item) {
if ($item > $now) {
return $item;
}
}
return null;
}
/**
* Main function to display the events.
*
* @param array
* @param object
*/
function printEvent(array $eventarray, object $date_helper) {
$start_datetime = $eventarray[0];
$event = $eventarray[1];
$day = toGerman($start_datetime->format("l"));
$start = $start_datetime->format("d.m.Y H:i");
$hyph = " - "; $hyph = " - ";
$uhr = " Uhr"; $uhr = " Uhr";
$komma = ", "; $komma = ", ";
$dateline = "{$day}{$komma}{$start}{$uhr}{$hyph}";
$event_start = $event->data['DTSTART']->value[0]; if ($event->URL != "") {
$event_url = lowerURL($event->data['URL']->parameter['value']); printHeadline($dateline, $event->SUMMARY, $event->URL);
$event_title = $event->data['SUMMARY']->value[0]; } else {
$event_location = trim($event->data['LOCATION']->value[0], '"'); printHeadline($dateline, $event->SUMMARY);
$event_descr = trim($event->data['DESCRIPTION']->value[0], '"'); }
if ($event->DESCRIPTION != "") {
$unix = $helper->fromiCaltoUnixDateTime($event_start); printDescription($event->DESCRIPTION);
$event_date = date('d.m.Y', $unix); }
$event_time = date('H:i', $unix); if ($event->LOCATION != "") {
$event_day = toGerman(date('l', $unix)); printLocation($event->LOCATION);
$dateline = "{$event_day}{$komma}{$event_date}{$hyph}{$event_time}{$uhr}"; }
printBottomline();
displayHeadline($dateline, $event_title);
displayLocation($event_location);
displayDescription($event_descr);
displayURL($event_url);
return true;
}
function displayHeadline(string $dateline, $event_title): bool
{
echo "\n<section class='termin'>\n";
echo "<p class='headline'>" . $dateline . ": " . $event_title . "</p>\n";
return true;
}
function displayLocation(string $location): bool
{
echo "<ul class='events'>\n";
echo "<li>$location</li>\n";
return true;
}
function displayDescription(string $description): bool
{
echo "<li>$description</li>\n";
return true;
}
function displayURL(string $url): bool
{
$stripped = trim($url, '"');
echo "<li><a href=" . $url . ">" . $stripped . "</a></li>\n";
echo "</ul>\n";
echo "</section>\n";
return true;
} }
/** /**
* Die Startfuktion für die Ausgabe der Termine als Tabelle in termine.php * Outputs the opening tags for section and ul, the date and time, and
* summary. ifi a url is given, the summary is a link to the corresponding
* wiki page.
*
* @param string
* @param string
*/ */
function printHeadline(string $dateline, string $summary, string $url=null) {
function printEventTable(): bool echo("\n<section class='termin'>");
{ if ($url == null) {
$events = initEvents(); echo("\n<p class='headline'>$dateline$summary</p>");
printTableHead(); } else {
foreach ($events as $event) echo("\n<p class='headline'>$dateline<a href='$url'>$summary</a></p>");
{
$event_array = getEventArray($event);
printTableItem($event_array);
} }
echo "\t</tbody>\n"; echo("\n<ul class='events'>");
echo "</table>\n";
return true;
}
function printTableHead()
{
echo "\n\r<table class='w3-table w3-bordered'>\n";
echo "\t<thead>\n";
echo "\t<tr>\n";
echo "\t\t<th>Datum</th>\n";
echo "\t\t<th>Wochentag</th>\n";
echo "\t\t<th>Zeit</th>\n";
echo "\t\t<th>Ort</th>\n";
echo "\t\t<th>Titel</th>\n";
echo "\t\t<th>Beschreibung</th>\n";
echo "\t</tr>\n";
echo "\t</thead>\n";
echo "\t<tbody>\n";
}
function printTableItem($event_array): bool
{
date_default_timezone_set("UTC");
$time = $event_array['DTSTART'];
$helper = new ZDateHelper();
$unix = $helper->fromiCaltoUnixDateTime($time);
$event_date = date('d.m.Y', $unix);
$event_time = date('H:i', $unix);
$event_day = toGerman(date('l', $unix));
$event_uid = $event_array['UID'];
$event_url = lowerURL($event_array['URL']);
$event_title = trim($event_array['SUMMARY'], '"');
$event_descr = trim($event_array['DESCRIPTION'], '"');
$event_location = trim($event_array['LOCATION'], '"');
echo "\t<tr id='" . $event_uid . "'>\n";
echo "\t\t<td>" . $event_date . "</td>\n";
echo "\t\t<td>" . $event_day . "</td>\n";
echo "\t\t<td>" . $event_time . " Uhr</td>\n";
echo "\t\t<td>" . $event_location . "</td>\n";
echo "\t\t<td>" . $event_title . "</td>\n";
echo "\t\t<td>" . $event_descr;
printURL($event_url);
echo "\t</tr>\n";
return true;
}
function printURL(string $url): bool
{
$stripped = trim($url, '"');
if ($url != '')
{
echo "</br><a class='event' href=" . $url . ">" . $stripped . "</a></td>\n";
}
else
{
echo "</td>\n";
}
return true;
} }
/** /**
* Funktionen, die von beiden Ausgaben benutzt werden. * Outputs the events description.
*
* @param string
*/ */
function printDescription(string $description) {
/** echo("\n<li>$description</li>");
* @return ZCiCalNode[]|null
*/
function initEvents(): ?array
/**
* Allgemeingültige Funktion zur Initialisierung. Enthält die Schritte, die
* von beiden Ausgaben gleichermaßen gebraucht werden.
* - Erstellen des iCalendar Objekts (initCalendar).
* - Schaut, ob der Kalender überhaupt Events enthält (printEventCount).
* - Sammel alle Events in einer Liste (grabEvents).
* Gibt zweidimmensionales assoziatives Array oder Null zurück.
*/
{
$iCalObj = initCalendar();
if (!isset ($iCalObj))
{
printError("Fehler beim Initialisieren des Kalenders");
return null;
}
$count = printEventCount($iCalObj);
if ($count == 0 or $count == false)
{
return null;
}
$events = grabEvents($iCalObj);
return $events;
} }
function initCalendar(): ?ZCiCal
/** /**
* Erstellt das Kalenderobjekt vom Typ ZCiCal. * Outputs the events location.
* Gibt das Kalenderobjekt oder Null zurück. *
* @param string
*/ */
{ function printLocation(string $location) {
$iCalFile = '../public/krautspace.ics'; $location = makeLinks($location);
$iCalString = file_get_contents($iCalFile); echo("\n<li>$location</li>");
if ($iCalString == false)
{
printError("Kann Kalenderdatei nicht lesen");
return null;
}
$iCalObj = new ZCiCal($iCalString);
return $iCalObj;
} }
function printEventCount(ZCiCal $iCalObj): ?int
/** /**
* Gibt die Anzahl der Events zurück, die das übergebene * Outputs the closing tags for ul and section.
* Kalenderobjekt enthält. Im Fehlerfall wird Null zurück
* gegeben.
*/ */
{ function printBottomline() {
$eventCount = $iCalObj->countEvents(); echo("\n</ul>");
if (!isset ($eventCount)) echo("\n</section>\n");
{
printError("Fehler beim Parsen des Kalenders");
return null;
}
// echo "<p>$eventCount anstehende Events</p>";
return $eventCount;
} }
function grabEvents(ZCiCal $iCalObj): ?array
{
/** /**
* Läuft durch das iCalendar objekt und sammelt alle Nodes vom Typ * Helper function to sort the events chronologically. Compares the first
* 'VEVENT' ein. Gibt ein Array mit Objekten vom Typ 'ZCiCalNode' zurück. * entry from the event array (DateTime object).
* Im Fehlerfall wird Null zurück gegeben. *
* @param array
* @param array
* @return integer
*/ */
$events = []; function compareEventStart(array $event_a, array $event_b): int {
if (isset ($iCalObj->tree->child)) // echo("Compare " . $event_a[0] . " and " . $event_b[0] . "\n");
{ $a = $event_a[0];
foreach ($iCalObj->tree->child as $node) $b = $event_b[0];
{ return $a <=> $b;
if ($node->getName() == "VEVENT")
{
$events[] = $node;
}
}
}
else
{
printError("Cant find nodes");
return null;
}
return $events;
} }
function getEventArray(ZCiCalNode $node): array
{
/** /**
* Bekommt eine Event Node vom Typ 'ZiCalNode' übergeben und extrahiert * Becomes the description string and makes urls contained in this string
* daraus die gewünschten Elemente. Bildet daraus ein zweidimmensionales * clickable. If anything goes wrong it returns the origin string.
* assoziatives Array. Gibt dieses Array zurück. *
* Wird derzeit nur von der tabellarischen Ausgabe referenziert, welche * @param string
+ momentan nicht genutzt wird. * @return string
*/ */
/** function makeLinks(string $description) {
* @var ZCiCalNode $node try {
* @var ZCiCalDataNode $event $reg_pattern = "/(((http|https)\:\/\/)|(www\.))[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,5}(\:[a-zA-Z0-9]+)?(\/\S*)?/";
*/ return $new = preg_replace($reg_pattern, '<a href="$0" target="_blank" rel="noopener noreferrer">$0</a>', $description);
$event = $node->data; } catch (Throwable $th) {
$event_array = []; return $description;
$keys = array('DTSTART', 'SUMMARY', 'DESCRIPTION', 'URL', 'LOCATION');
foreach ($keys as $key)
{
$event_array[$key] = $event[$key]->value[0];
if ($key === 'DTSTART')
{
if (isset ($event[$key]->parameter['tzid']))
{
$event_array['TZ'] = $event[$key]->parameter['tzid'];
}
}
else if ($key === 'URL')
{
$event_array[$key] = $event[$key]->parameter['value'];
}
} }
return $event_array;
} }
function printError($errMsg) /**
{ * Translates the english weekday names to german.
echo "\n\r<p>$errMsg</p>\n\r"; *
return true; * @param string
} * @return string | null
*/
function toGerman(string $day): string function toGerman(string $day): ?string
{ {
switch ($day) switch ($day)
{ {
@ -357,131 +205,91 @@ function toGerman(string $day): string
case 'Sunday': case 'Sunday':
return 'Sonntag'; return 'Sonntag';
default: default:
return '?'; return null;
} }
} }
function lowerURL(string $url): string
{
$old = array('HTTPS', 'HTTP', 'FTP', 'WWW', 'SSH');
$new = array('https', 'http', 'ftp', 'www', 'ssh');
$new_url = str_replace($old, $new, $url);
return $new_url;
}
function calculateNextStart(int $unix_start, string $rrule): int ///////////////////////////////////////////////////////////////////////////
/** /// start des programmes
* Berechnet für wiederkehrende Termine den aktuell nächsten Termin. ///////////////////////////////////////////////////////////////////////////
* dabei werden zur Zeit nur der der Zeitraum zwischen zwei Terminen
* und eine mögliche Anzahl der Termine berücksichtigt. Gibt den neuen
* Termin als Unix-Zeitstempel zurück.
*/
{
$counter = 0;
$rule_array = getRuleArray($rrule);
if (isset ($rule_array['COUNT']))
{
$count = $rule_array['COUNT'];
}
if (isset ($rule_array['FREQ']))
{
$frequency = $rule_array['FREQ'];
}
if (isset ($rule_array['INTERVAL']))
{
$interval = $rule_array['INTERVAL'];
}
if (isset ($rule_array['UNTIL']))
{
//todo implement
$until_string = $rule_array['UNTIL'];
}
$freq_offset = getOffset($frequency);
if (isset ($interval))
{
$offset = $freq_offset * $interval;
}
else
{
$offset = $freq_offset;
}
while ($unix_start <= time())
{
if (isset ($count))
{
if ($counter >= $count)
{
break;
}
}
$unix_start = $unix_start + $offset;
$counter = $counter + 1;
}
return $unix_start;
}
function getOffset(string $frequence): int
{
switch ($frequence)
{
case 'HOURLY':
return 3600;
case 'DAILY':
return 86400;
case 'WEEKLY':
return 604800;
default:
return 1;
}
}
function getRuleArray(string $rrule): array
/**
* Zerlegt den String einer RRULE und gibt die einzelnen Elemente als
* assoziatives Array zurück.
*/
{
$rule_array = [];
$rule_strings = explode(';', $rrule);
foreach ($rule_strings as $r_string)
{
$rule = explode('=', $r_string);
$rule_array[$rule[0]] = $rule[1];
}
return $rule_array;
}
function EventIsPast(int $unix_start): bool
/**
* Prüft, ob die übergebenen Unixzeit älter als der aktuelle Tag ist. Gibt
* Wahr oder Falsch zurück.
*/
{
$event_date = date('d.m.Y', $unix_start);
$day_end = strtotime($event_date) + 86400;
$actual_date = time();
if ($day_end < $actual_date)
{
return true;
}
return false;
}
/** /**
* Bekommt zwei Eventnodes übergeben und vergleicht deren Startdatum. Die * The main function.
* Funktion wird intern von ausort() benutzt, um das Array mit den Eventnodes
* nach Datum zu sortieren.
* *
* @param ZCiCalNode $event_a
* @param ZCiCalNode $event_b
* @return int
*/ */
function compareEventStart(ZCiCalNode $event_a, ZCiCalNode $event_b): int function printEventList(): bool {
{ error_log("getEvents called");
$a = $event_a->data['DTSTART']->value[0]; date_default_timezone_set("Europe/Berlin");
$b = $event_b->data['DTSTART']->value[0]; $today_datetime = new DateTime();
return $a <=> $b; date_time_set($today_datetime, 0, 0, 0, 0);
$date_helper = new VObject\DateTimeParser();
$eventlist = [];
$next_events = [];
// einlesen der kalenderdatei
$vcalendar = initCalendar();
if ($vcalendar == null) {
error_log("getEvents unsuccessful terminated");
return false;
}
// die events aus dem kalender herausziehen
$eventlist = grabEvents($vcalendar);
if ($eventlist == null) {
error_log("gabEvent returns null");
return false;
}
elseif (count($eventlist) == 0) {
echo("\n<p>Keine Termine gefunden</p>\n");
return false;
}
// durch die liste der events laufen. wir holen uns den starttermin und
// wandeln ihn in ein datetime objekt um. liegt das in der vergangenheit
// und der termin hat eine rrule, holen wir uns einen iterator über die
// rrule (dazu brauchen wir die uid) und versuche den nächsten gültigen
// termin zu bekommen. gibt es einen gültigen termin, wird das event mit
// dem neuen starttermin an die liste der relevanten termine angehängt.
// ist der starttermin von anfang an in der zukunft, dann wird er
// natürlich auch angehängt.
foreach ($eventlist as $event) {
$next_event = [];
$e_uid = $event->UID;
$e_start = $event->DTSTART;
$e_summary = $event->SUMMARY;
$e_description = $event->DESCRIPTION;
$e_location = $event->LOCATION;
$e_url = $event->URL;
$start_datetime = $date_helper->parseDateTime($e_start);
if ($start_datetime < $today_datetime) {
if (isset($event->RRULE)) {
$rriter = new VObject\RecurrenceIterator($vcalendar, $e_uid);
$start_datetime = getNextDate($rriter, $today_datetime);
if ($start_datetime == null) {
continue;
} else {
array_push($next_events, array($start_datetime, $event));
}
}
} else {
array_push($next_events, array($start_datetime, $event));
}
}
// liste der anstehenden events nach dem begin sortieren
usort($next_events, "compareEventStart");
// die sortierte liste ausgeben
foreach ($next_events as $event) {
printEvent($event, $date_helper);
}
error_log("getEvents successful terminated");
return true;
} }