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 * Zeitangabe des iCal-Formates in Datum, Uhrzeit und Wochentag umgewandelt. * Anschließend erfolgt die Ausgabe der einzelnen Teile. */ { date_default_timezone_set("UTC"); $helper = new ZDateHelper(); $hyph = " - "; $uhr = " Uhr"; $komma = ", "; $event_start = $event->data['DTSTART']->value[0]; $event_url = lowerURL($event->data['URL']->parameter['value']); $event_title = $event->data['SUMMARY']->value[0]; $event_location = trim($event->data['LOCATION']->value[0], '"'); $event_descr = trim($event->data['DESCRIPTION']->value[0], '"'); $unix = $helper->fromiCaltoUnixDateTime($event_start); $event_date = date('d.m.Y', $unix); $event_time = date('H:i', $unix); $event_day = toGerman(date('l', $unix)); $dateline = "{$event_day}{$komma}{$event_date}{$hyph}{$event_time}{$uhr}"; displayHeadline($dateline, $event_title); displayLocation($event_location); displayDescription($event_descr); displayURL($event_url); return true; } function displayHeadline(string $dateline, $event_title): bool { echo "\n
\n"; echo "

" . $dateline . ": " . $event_title . "

\n"; return true; } function displayLocation(string $location): bool { echo "\n"; echo "
\n"; return true; } /** * Die Startfuktion für die Ausgabe der Termine als Tabelle in termine.php */ function printEventTable(): bool { $events = initEvents(); printTableHead(); foreach ($events as $event) { $event_array = getEventArray($event); printTableItem($event_array); } echo "\t\n"; echo "\n"; return true; } function printTableHead() { echo "\n\r\n"; echo "\t\n"; echo "\t\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\n"; echo "\t\n"; echo "\t\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\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\t\n"; echo "\t\t\n"; return true; } function printURL(string $url): bool { $stripped = trim($url, '"'); if ($url != '') { echo "
" . $stripped . "\n"; } else { echo "\n"; } return true; } /** * Funktionen, die von beiden Ausgaben benutzt werden. */ /** * @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. * Gibt das Kalenderobjekt oder Null zurück. */ { $iCalFile = '../public/krautspace.ics'; $iCalString = file_get_contents($iCalFile); 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 * Kalenderobjekt enthält. Im Fehlerfall wird Null zurück * gegeben. */ { $eventCount = $iCalObj->countEvents(); if (!isset ($eventCount)) { printError("Fehler beim Parsen des Kalenders"); return null; } // echo "

$eventCount anstehende Events

"; return $eventCount; } function grabEvents(ZCiCal $iCalObj): ?array { /** * Läuft durch das iCalendar objekt und sammelt alle Nodes vom Typ * 'VEVENT' ein. Gibt ein Array mit Objekten vom Typ 'ZCiCalNode' zurück. * Im Fehlerfall wird Null zurück gegeben. */ $events = []; if (isset ($iCalObj->tree->child)) { foreach ($iCalObj->tree->child as $node) { 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 * daraus die gewünschten Elemente. Bildet daraus ein zweidimmensionales * assoziatives Array. Gibt dieses Array zurück. * Wird derzeit nur von der tabellarischen Ausgabe referenziert, welche + momentan nicht genutzt wird. */ /** * @var ZCiCalNode $node * @var ZCiCalDataNode $event */ $event = $node->data; $event_array = []; $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) { echo "\n\r

$errMsg

\n\r"; return true; } 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 '?'; } } 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 /** * 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 * 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 { $a = $event_a->data['DTSTART']->value[0]; $b = $event_b->data['DTSTART']->value[0]; return $a <=> $b; }
DatumWochentagZeitOrtTitelBeschreibung
" . $event_date . "" . $event_day . "" . $event_time . " Uhr" . $event_location . "" . $event_title . "" . $event_descr; printURL($event_url); echo "\t