Open bvdputte opened 6 years ago
i have tried that one but its using 2009 RFC 5545
standard. so i would not recommend it wholeheartedly.
had some troubles with GMT+1 timezones being set correctly for apple and outlook to be recognized correctly. https://github.com/markuspoerschke/iCal/blob/master/examples/example4b.php
also verify seems like a good idea. https://icalendar.org/validator.html
mine was also using https://github.com/mzur/kirby-calendar-plugin
here is the main factory function collecting all events. good luck.
<?php
public function icsEvents($withAttendees = false) {
$allEvents = array();
date_default_timezone_set('Europe/Berlin');
if($this->calendar()->isNotEmpty()) {
if($calendar = calendar($this->calendar()->yaml())) {
foreach ($calendar->getAllEvents() as $event) {
$kennung = $event->getField('kennung');
$ts_start = $event->getBeginTimestamp();
$ts_ende = $event->getEndTimestamp();
$summary = $this->title()->value();
$desc = $this->desc()->value();
$timeZone = new \DateTimeZone('Europe/Berlin');
$timeZoneString = 'Europe/Berlin';
$organizer = new \Eluceo\iCal\Property\Event\Organizer(
'MAILTO:'.site()->kontaktemail()->value(),
['CN' => site()->title()->value()]
);
$loc = $event->getField('eventlocation');
if(strlen($loc) == 0) {
$loc = $this->location()->value();
}
// https://github.com/markuspoerschke/iCal
// https://github.com/markuspoerschke/iCal/blob/master/src/Component/Event.php
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent
->setModified(new \DateTime(date('c', $this->modified()), $timeZone))
->setUrl($this->url())
->setDtStart(new \DateTime(date('c', $ts_start), $timeZone))
->setDtEnd(new \DateTime(date('c', $ts_ende), $timeZone))
//->setNoTime(true)
->setLocation($loc)
->setUseTimezone(true)
->setSummary($summary)
->setDescription($desc)
->setOrganizer($organizer);
$vEvent->setTimezoneString($timeZoneString);
if($withAttendees) {
// get buchungen -> attendees
$buchungen = $this->children()
->filterBy('terminkennung', $kennung);
//$attendees = new Eluceo\iCal\Property\Event\Attendees();
foreach ($buchungen as $b) {
// http://www.kanzaki.com/docs/ical/attendee.html
$params = [
'CU' => 'INDIVIDUAL', // http://www.kanzaki.com/docs/ical/cutype.html
'CN' => '#'.str::upper($b->buchungsToken()).' '.$b->vorname()->value().' '.$b->nachname()->value(),
];
// http://www.kanzaki.com/docs/ical/partstat.html
if($b->buchungsart() == self::ART_VERBINDLICH) {
$params['PARTSTAT'] = 'ACCEPTED';
}
/*
else if($b->buchungsart() == self::ART_RESERVIERUNG) {
$params['PARTSTAT'] = 'TENTATIVE';
} else if($b->buchungsart() == self::ART_NACHWEIS) {
$params['PARTSTAT'] = 'NEEDS-ACTION';
} else if($b->buchungsart() == self::ART_STORNIERT) {
$params['PARTSTAT'] = 'DECLINED';
}
*/
$email = trim($b->email()->value());
$vEvent->addAttendee($email, $params);
}
}
$allEvents[] = $vEvent;
}
}
}
return $allEvents;
}
complemented by a class for rendering ical and serving the file
class KirbyICS {
public static function render($page, $options = null, $events = null) {
$t = $page ? $page->title()->value() : '';
$title = a::get($options, 'title', $t);
$vCalendar = new \Eluceo\iCal\Component\Calendar($title);
if($events && is_array($events)) {
foreach($events as $vEvent) {
// TODO: should check class of event object
$vCalendar->addComponent($vEvent);
}
}
return $vCalendar->render();
}
public static function ics($page, $options = null, $events = null) {
$title = a::get($options, 'title', $page->title()->value());
$filename = a::get($options, 'filename', str::lower($title));
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="'.$filename.'.ics"');
echo self::render($page, $options, $events);
}
}
e.g. https://github.com/markuspoerschke/iCal