| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/seaside.pacim.de/web/ |
Upload File : |
<?php
die();
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="kreuzfahrten_2026.ics"');
$pdo = new PDO(
'mysql:host=localhost;dbname=seaside_pas;charset=utf8mb4',
'seaside_pas',
'Kmyuk9sYP9EeXqAywJ4V',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
/*
* Doppelte aussortieren:
* gleiche �berschrift + gleiches Datum => nur 1 Termin
* Wir nehmen pro Gruppe den kleinsten event_calendar_id und den fr�hesten Begin
*/
$sql = "
SELECT
MIN(event_calendar_id) AS source_id,
event_calendar_title AS title,
DATE(event_calendar_begin) AS event_date,
MIN(event_calendar_begin) AS start_datetime
FROM pacim_events
WHERE
YEAR(event_calendar_begin) = 2026
AND event_calendar_active = 1
GROUP BY
DATE(event_calendar_begin),
event_calendar_title
ORDER BY
event_date ASC,
title ASC
";
$stmt = $pdo->query($sql);
$timezoneLocal = new DateTimeZone('Europe/Berlin');
$timezoneUtc = new DateTimeZone('UTC');
/*
* ICS-sichere Ausgabe
*/
function icsEscape(string $value): string
{
$value = str_replace("\\", "\\\\", $value);
$value = str_replace(";", "\;", $value);
$value = str_replace(",", "\,", $value);
$value = preg_replace("/\r\n|\r|\n/", "\\n", $value);
return $value;
}
/*
* Lange Zeilen f�r ICS falten
*/
function icsLine(string $key, string $value): string
{
$line = $key . ':' . $value;
$max = 73;
if (strlen($line) <= $max) {
return $line . "\r\n";
}
$out = '';
while (strlen($line) > $max) {
$out .= substr($line, 0, $max) . "\r\n" . ' ';
$line = substr($line, $max);
$max = 72;
}
$out .= $line . "\r\n";
return $out;
}
echo "BEGIN:VCALENDAR\r\n";
echo "VERSION:2.0\r\n";
echo "PRODID:-//Kreuzfahrten 2026 Rostock//DE\r\n";
echo "CALSCALE:GREGORIAN\r\n";
echo "METHOD:PUBLISH\r\n";
echo icsLine('X-WR-CALNAME', icsEscape('Kreuzfahrten 2026 Rostock'));
echo icsLine('X-WR-TIMEZONE', 'Europe/Berlin');
while ($row = $stmt->fetch()) {
$date = new DateTime($row['event_date'], $timezoneLocal);
$start = clone $date;
$start->setTime(7, 0, 0);
$end = clone $date;
$end->setTime(16, 0, 0);
$startUtc = clone $start;
$startUtc->setTimezone($timezoneUtc);
$endUtc = clone $end;
$endUtc->setTimezone($timezoneUtc);
$eventDateForUrl = $date->format('Y-m-d');
$eventUrl = 'https://seaside.pacim.de/mobile/calendar.php?token=nico&date=' . $eventDateForUrl;
/*
* Stabile UID:
* gleiches Datum + gleicher Titel => immer gleiche UID
* so werden Re-Imports und Feed-Updates beherrschbar
*/
$uidSource = $row['title'] . '|' . $row['event_date'];
$uid = md5($uidSource) . '@pacim-calendar';
/*
* LAST-MODIFIED / DTSTAMP
*/
$dtStamp = gmdate('Ymd\THis\Z');
echo "BEGIN:VEVENT\r\n";
echo icsLine('UID', $uid);
echo icsLine('DTSTAMP', $dtStamp);
echo icsLine('DTSTART', $startUtc->format('Ymd\THis\Z'));
echo icsLine('DTEND', $endUtc->format('Ymd\THis\Z'));
echo icsLine('SUMMARY', icsEscape($row['title']));
echo icsLine('DESCRIPTION', icsEscape("Details zum Termin:\n" . $eventUrl));
echo icsLine('URL', $eventUrl);
/*
* Praktisch zum Wiederfinden
*/
echo icsLine('CATEGORIES', icsEscape('PACIM,Kreuzfahrten 2026'));
/*
* Eigene Kennung aus DB, falls du sp�ter doch API-seitig matchen willst
*/
echo icsLine('X-PACIM-ID', (string)$row['source_id']);
echo "END:VEVENT\r\n";
}
echo "END:VCALENDAR\r\n";