295 lines
7.8 KiB
PHP
295 lines
7.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* file: getEvents.php
|
|
* date: 20.11.2022
|
|
* user: bernd@nr18.space
|
|
*/
|
|
|
|
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");
|
|
|
|
/**
|
|
* Reads the content of the given ical file and creates with this string a
|
|
* vcalendar object.
|
|
*
|
|
* @return vCalendar object | null
|
|
*/
|
|
function initCalendar(): ?object {
|
|
try {
|
|
$data = file_get_contents(ICAL_FILE);
|
|
$vcalendar = VObject\Reader::read(
|
|
$data
|
|
);
|
|
return $vcalendar;
|
|
} catch (Throwable $th) {
|
|
error_log("Failed to read calendar file.");
|
|
error_log($th->getMessage(), 0);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Grabs all VEVENTS from vCalendar object, append they to a list and
|
|
* returns the list.
|
|
*
|
|
* @param vCalendar object
|
|
* @return list | null
|
|
*/
|
|
function grabEvents(object $vcalendar): ?array {
|
|
$eventlist = [];
|
|
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 = " - ";
|
|
$uhr = " Uhr";
|
|
$komma = ", ";
|
|
$dateline = "{$day}{$komma}{$start}{$uhr}{$hyph}";
|
|
|
|
if ($event->URL != "") {
|
|
printHeadline($dateline, $event->SUMMARY, $event->URL);
|
|
} else {
|
|
printHeadline($dateline, $event->SUMMARY);
|
|
}
|
|
if ($event->DESCRIPTION != "") {
|
|
printDescription($event->DESCRIPTION);
|
|
}
|
|
if ($event->LOCATION != "") {
|
|
printLocation($event->LOCATION);
|
|
}
|
|
printBottomline();
|
|
}
|
|
|
|
/**
|
|
* 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) {
|
|
echo("\n<section class='termin'>");
|
|
if ($url == null) {
|
|
echo("\n<p class='headline'>$dateline$summary</p>");
|
|
} else {
|
|
echo("\n<p class='headline'>$dateline<a href='$url'>$summary</a></p>");
|
|
}
|
|
echo("\n<ul class='events'>");
|
|
}
|
|
|
|
/**
|
|
* Outputs the events description.
|
|
*
|
|
* @param string
|
|
*/
|
|
function printDescription(string $description) {
|
|
echo("\n<li>$description</li>");
|
|
}
|
|
|
|
/**
|
|
* Outputs the events location.
|
|
*
|
|
* @param string
|
|
*/
|
|
function printLocation(string $location) {
|
|
$location = makeLinks($location);
|
|
echo("\n<li>$location</li>");
|
|
}
|
|
|
|
/**
|
|
* Outputs the closing tags for ul and section.
|
|
*/
|
|
function printBottomline() {
|
|
echo("\n</ul>");
|
|
echo("\n</section>\n");
|
|
}
|
|
|
|
/**
|
|
* Helper function to sort the events chronologically. Compares the first
|
|
* entry from the event array (DateTime object).
|
|
*
|
|
* @param array
|
|
* @param array
|
|
* @return integer
|
|
*/
|
|
function compareEventStart(array $event_a, array $event_b): int {
|
|
// echo("Compare " . $event_a[0] . " and " . $event_b[0] . "\n");
|
|
$a = $event_a[0];
|
|
$b = $event_b[0];
|
|
return $a <=> $b;
|
|
}
|
|
|
|
/**
|
|
* Becomes the description string and makes urls contained in this string
|
|
* clickable. If anything goes wrong it returns the origin string.
|
|
*
|
|
* @param string
|
|
* @return string
|
|
*/
|
|
function makeLinks(string $description) {
|
|
try {
|
|
$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);
|
|
} catch (Throwable $th) {
|
|
return $description;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Translates the english weekday names to german.
|
|
*
|
|
* @param string
|
|
* @return string | null
|
|
*/
|
|
function toGerman(string $day): ?string
|
|
{
|
|
switch ($day)
|
|
{
|
|
case 'Monday':
|
|
return 'Montag';
|
|
case 'Tuesday':
|
|
return 'Dienstag';
|
|
case 'Wednesday':
|
|
return 'Mittwoch';
|
|
case 'Thursday':
|
|
return 'Donnerstag';
|
|
case 'Friday':
|
|
return 'Freitag';
|
|
case 'Saturday':
|
|
return 'Samstag';
|
|
case 'Sunday':
|
|
return 'Sonntag';
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
/// start des programmes
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* The main function.
|
|
*
|
|
*/
|
|
function printEventList(): bool {
|
|
error_log("getEvents called");
|
|
date_default_timezone_set("Europe/Berlin");
|
|
$today_datetime = new DateTime();
|
|
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;
|
|
}
|
|
|