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
"); if ($url == null) { echo("\n

$dateline$summary

"); } else { echo("\n

$dateline$summary

"); } echo("\n"); echo("\n
\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, '$0', $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

Keine Termine gefunden

\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; }