Files
schachfreunde-badsteben/site/collections/termine.php
T
2025-12-18 19:00:05 +01:00

156 lines
3.9 KiB
PHP

<?php
// URL der öffentlichen ICS-Datei
define(
'CAL_URL',
'https://calendar.google.com/calendar/ical/jv1bq94un3ivoa8ka0rk9ngq4k%40group.calendar.google.com/public/basic.ics',
);
function format_ics_date($date)
{
// Unterstützt sowohl ganztägige als auch Zeitangaben
if (strpos($date, 'T') !== false) {
$dt = DateTime::createFromFormat('Ymd\THis', substr($date, 0, 15));
return $dt ? $dt->format('d.m.Y H:i') : $date;
} else {
$dt = DateTime::createFromFormat('Ymd', $date);
return $dt ? $dt->format('d.m.Y') : $date;
}
}
function format_ics_date_with_timezone($date, $timezone = null)
{
// Unterstützt sowohl ganztägige als auch Zeitangaben
if (strpos($date, 'T') !== false) {
$dt = null;
// Prüfe ob es eine UTC-Zeit ist (endet mit Z)
if (substr($date, -1) === 'Z') {
// UTC-Zeit: 20250405T130000Z
$utc_date = substr($date, 0, -1); // Entferne das Z
$dt = DateTime::createFromFormat('Ymd\THis', $utc_date, new DateTimeZone('UTC'));
} elseif ($timezone) {
// Zeitzone angegeben: 20250405T130000 mit TZID
try {
$dt = new DateTime($date, new DateTimeZone($timezone));
} catch (Exception $e) {
// Fallback auf lokale Zeit
$dt = DateTime::createFromFormat('Ymd\THis', substr($date, 0, 15));
}
} else {
// Lokale Zeit ohne Zeitzone
$dt = DateTime::createFromFormat('Ymd\THis', substr($date, 0, 15));
}
if ($dt) {
// ISO 8601 Format für JavaScript
$iso_date = $dt->format('Y-m-d\TH:i:sP'); // P = Zeitzone
$display_date = $dt->format('d.m.Y H:i');
return [
'iso' => $iso_date,
'display' => $display_date,
'has_time' => true,
];
}
return [
'iso' => $date,
'display' => $date,
'has_time' => true,
];
} else {
$dt = DateTime::createFromFormat('Ymd', $date);
if ($dt) {
$iso_date = $dt->format('Y-m-d');
$display_date = $dt->format('d.m.Y');
return [
'iso' => $iso_date,
'display' => $display_date,
'has_time' => false,
];
}
return [
'iso' => $date,
'display' => $date,
'has_time' => false,
];
}
}
// Cache für 24 Stunden (in Minuten)
$cacheDuration = 24 * 60;
$cacheId = 'google_calendar_events';
$cache = kirby()->cache('pages');
// Termine parsen
function parse_ics($ics)
{
$lines = explode("\n", $ics);
$events = [];
$event = [];
$inEvent = false;
foreach ($lines as $line) {
$line = trim($line);
if ($line === 'BEGIN:VEVENT') {
$inEvent = true;
$event = [];
} elseif ($line === 'END:VEVENT') {
$inEvent = false;
$events[] = $event;
} elseif ($inEvent) {
// Property kann Parameter enthalten, z.B. DTSTART;TZID=Europe/Berlin:20240701T19000000
$parts = explode(':', $line, 2);
if (count($parts) === 2) {
$key = $parts[0];
$val = $parts[1];
// Zeitzoneninformation extrahieren
$timezone = null;
if (preg_match('/TZID=([^:;]+)/', $key, $matches)) {
$timezone = $matches[1];
}
// Nur den eigentlichen Property-Namen extrahieren
$cleanKey = strtoupper(preg_replace('/;.+$/', '', $key));
$event[$cleanKey] = $val;
// Zeitzoneninformation separat speichern
if ($timezone && in_array($cleanKey, ['DTSTART', 'DTEND'])) {
$event[$cleanKey . '_TZID'] = $timezone;
}
}
}
}
return $events;
}
return function () use ($cache, $cacheId, $cacheDuration) {
// Versuche Daten aus dem Cache zu laden
$events = $cache->get($cacheId);
if ($events === null) {
// Wenn nicht im Cache, neu laden
$ics = @file_get_contents(CAL_URL);
if (!$ics) {
// Fehler beim Laden (z.B. 429 Error)
return null;
}
// Termine parsen
$events = parse_ics($ics);
// In Cache speichern
$cache->set($cacheId, $events, $cacheDuration);
}
return $events;
};