Files
schachfreunde-badsteben/site/snippets/termine.php
T

112 lines
4.5 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');
// ICS-Datei laden
$ics = @file_get_contents(CAL_URL);
if (!$ics) {
echo '<div class="text-red-600">Kalender konnte nicht geladen werden.</div>';
return;
}
// 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];
// Nur den eigentlichen Property-Namen extrahieren
$key = strtoupper(preg_replace('/;.+$/', '', $key));
$event[$key] = $val;
}
}
}
return $events;
}
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;
}
}
$events = parse_ics($ics);
// Nur Events mit DTSTART berücksichtigen
$events = array_filter($events, function($event) {
return isset($event['DTSTART']) && !empty($event['DTSTART']);
});
// Nach Datum sortieren
usort($events, function($a, $b) {
return strcmp($a['DTSTART'], $b['DTSTART']);
});
// Aktuelles Datum
$today = (new DateTime())->format('Ymd');
// Nur zukünftige Termine anzeigen
$future_events = array_filter($events, function($event) use ($today) {
return isset($event['DTSTART']) && $event['DTSTART'] >= $today;
});
?>
<section class="py-24 bg-sf_grau-50">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<?php if (empty($future_events)): ?>
<div class="text-gray-500">Keine bevorstehenden Termine gefunden.</div>
<?php else: ?>
<div class="overflow-x-auto">
<table class="min-w-full border border-gray-200 bg-white rounded-lg shadow">
<thead>
<tr class="bg-gray-100">
<th class="py-2 px-4 border-b text-left">Datum</th>
<th class="py-2 px-4 border-b text-left">Uhrzeit</th>
<th class="py-2 px-4 border-b text-left">Titel</th>
<th class="py-2 px-4 border-b text-left">Ort</th>
<th class="py-2 px-4 border-b text-left">Beschreibung</th>
</tr>
</thead>
<tbody>
<?php foreach ($future_events as $event): ?>
<?php
$start = $event['DTSTART'] ?? '';
$end = $event['DTEND'] ?? '';
$summary = $event['SUMMARY'] ?? '';
$location = $event['LOCATION'] ?? '';
$desc = $event['DESCRIPTION'] ?? '';
$date = format_ics_date($start);
$time = (str_contains($start, 'T')) ? substr($date, 11) : 'ganztägig';
$date = substr($date, 0, 10);
?>
<tr class="hover:bg-gray-50">
<td class="py-2 px-4 border-b whitespace-nowrap"><?php echo htmlspecialchars($date); ?></td>
<td class="py-2 px-4 border-b whitespace-nowrap"><?php echo htmlspecialchars($time); ?></td>
<td class="py-2 px-4 border-b"><?php echo htmlspecialchars($summary); ?></td>
<td class="py-2 px-4 border-b"><?php echo htmlspecialchars($location); ?></td>
<td class="py-2 px-4 border-b"><?php echo nl2br(htmlspecialchars($desc)); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</section>