forked from Krautspace/webseite-krautspace
kalenderdatei ueberarbeitet, getEvents auf VObject von sabre.io umgestellt
This commit is contained in:
parent
4d08672148
commit
78b461609f
2 changed files with 243 additions and 435 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
* Ausgabefunktion auf. Gibt einen Boolean zurück.
|
|
||||||
*/
|
|
||||||
$events = initEvents();
|
|
||||||
$helper = new ZDateHelper();
|
|
||||||
date_default_timezone_set("UTC");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Startdatum für wiederkehrende Termine aktualisieren
|
|
||||||
*
|
*
|
||||||
* @var ZCiCalNode $event
|
* @return vCalendar object | null
|
||||||
*/
|
*/
|
||||||
foreach ($events as $event)
|
function initCalendar(): ?object {
|
||||||
{
|
try {
|
||||||
/**
|
$data = file_get_contents(ICAL_FILE);
|
||||||
* @var ZCiCalDataNode $eventDTStart
|
$vcalendar = VObject\Reader::read(
|
||||||
*/
|
$data
|
||||||
$eventDTStart = $event->data['DTSTART'];
|
);
|
||||||
/** @var string[] $eventDTStartValues */
|
return $vcalendar;
|
||||||
$eventDTStartValues = $eventDTStart->value;
|
} catch (Throwable $th) {
|
||||||
$event_start = $eventDTStartValues[0] ?? '';
|
error_log("Failed to read calendar file.");
|
||||||
$unix_start = $helper->fromiCaltoUnixDateTime($event_start);
|
error_log($th->getMessage(), 0);
|
||||||
$rrule = $event->data['RRULE']->value[0];
|
return null;
|
||||||
|
|
||||||
//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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue