I once did this, a bit in a hurry:
site/models/event.php
<?php
use Kirby\Cms\Page;
use Kirby\Cms\File;
use Jsvrcek\ICS\Model\Calendar;
use Jsvrcek\ICS\Model\CalendarEvent;
use Jsvrcek\ICS\Model\Description\Location;
use Jsvrcek\ICS\Utility\Formatter;
use Jsvrcek\ICS\CalendarStream;
use Jsvrcek\ICS\CalendarExport;
class ICSFile extends File {
private $eventStart = null;
private $eventEnd = null;
private $eventName = null;
private $wholeDay = false;
private $eventLocation = null;
private $timezone = null;
// this needs to exist or deleting the page won't work
public function delete(): bool
{
return true;
}
public function __construct($eventPage) {
$this->eventStart = new DateTime($eventPage->date(), $this->timezone);
if($eventPage->enddate()->isEmpty()) {
$this->eventEnd = clone $this->eventStart;
$this->eventEnd->setTime(23,59,59);
if($this->eventStart->format('H:i:s') === '00:00:00') {
$this->wholeDay = true;
}
} else {
$this->eventEnd = new DateTime($eventPage->enddate(), $this->timezone);
}
$this->eventName = $eventPage->title();
$this->eventLocation = $eventPage->place();
$this->eventUrl = $eventPage->url() . '.ics';
$this->timezone = new DateTimeZone('Europe/Zurich');
parent::__construct([
'filename' => 'calendar.ics',
'url' => $this->eventUrl,
'template' => 'attachment',
'parent' => $eventPage,
'content' => []
]);
}
public function writeContent(array $data, string $languageCode = null): bool {
// not supported
}
public function read() {
$event = new CalendarEvent();
$location = new Location();
$location
->setName($this->eventLocation);
$event
->setStart($this->eventStart)
->setEnd($this->eventEnd)
->setAllDay($this->wholeDay)
->setSummary($this->eventName)
->addLocation($location);
$calendar = new Calendar();
$calendar
->setProdId('s1syphos')
->setTimezone($this->timezone)
->addEvent($event);
$calendarExport = new CalendarExport(new CalendarStream, new Formatter());
$calendarExport->addCalendar($calendar);
return $calendarExport->getStream();
}
}
class EventPage extends Page {
public function files() {
$files = parent::files();
$virtualFile = new ICSFile($this);
$files->add($virtualFile);
return $files;
}
}
It uses this GitHub - jasvrcek/ICS: Object-oriented php library for creating .ics iCal files to format the ICS file - you probably have your own solution, but I guess you’ll get the idea