core/source/overwrites/caldav_backend.php
2025-09-09 21:17:19 +00:00

310 lines
5.7 KiB
PHP

<?php
namespace davigil\overwrites;
require_once('vendor/autoload.php');
require_once('helpers/call.php');
require_once('helpers/ics.php');
require_once('model.php');
require_once('sources/_interface.php');
require_once('conf.php');
/**
*/
class class_caldav_backend
extends \Sabre\CalDAV\Backend\AbstractBackend
implements \Sabre\CalDAV\Backend\BackendInterface
{
/**
*/
private \davigil\sources\interface_source $source;
/**
*/
public function __construct(
\davigil\sources\interface_source $source
)
{
// parent::__construct();
$this->source = $source;
}
/**
*/
private function hash_tag(
string $tag
) : string
{
return \hash('sha256', $tag);
}
/**
*/
private function encode_tag(
string $tag
) : string
{
return \davigil\helpers\call\convey(
$tag,
[
fn($x) => \strtolower($x),
fn($x) => \preg_replace('/ä/', 'ae', $x),
fn($x) => \preg_replace('/ö/', 'oe', $x),
fn($x) => \preg_replace('/ü/', 'ue', $x),
fn($x) => \preg_replace('/ß/', 'sz', $x),
fn($x) => \preg_replace('/\-/', '', $x),
fn($x) => \preg_replace('/ /', '-', $x),
fn($x) => \preg_replace('/[^a-zA-Z0-9_\-]/s', '_', $x),
]
);
}
/**
* @todo outsource
*/
private function event_to_vevent(
\davigil\model\struct_event $event
) : \davigil\helpers\ics\struct_vevent
{
$vevent = new \davigil\helpers\ics\struct_vevent();
{
$vevent->uid = $event->id;
$vevent->dtstamp = \davigil\helpers\ics\datetime_from_unix_timestamp($event->begin);
$vevent->dtstart = new \davigil\helpers\ics\struct_dt(
'',
\davigil\helpers\ics\datetime_from_unix_timestamp($event->begin)
);
$vevent->dtend = (
($event->end === null)
?
null
:
new \davigil\helpers\ics\struct_dt(
'',
\davigil\helpers\ics\datetime_from_unix_timestamp($event->end)
)
);
$vevent->summary = $event->title;
$vevent->location = $event->location;
$vevent->description = $event->description;
$vevent->class = \davigil\helpers\ics\enum_class::public_;
$vevent->categories = $event->tags;
}
return $vevent;
}
/**
* @todo outsource
*/
private function events_to_vcalendar(
array $events
) : \davigil\helpers\ics\struct_vcalendar
{
$vcalendar = new \davigil\helpers\ics\struct_vcalendar();
{
$vcalendar->version = '2.0';
/**
* @todo conf
*/
$vcalendar->prodid = 'davigil';
$vcalendar->method = 'PUBLISH';
$vcalendar->events = \array_map(
fn($event) => $this->event_to_vevent($event),
$events
);
}
return $vcalendar;
}
/**
* [implementation]
*/
public function getCalendarsForUser(
$principalUri
)
{
$calendar = $this->source->get([]);
$tags = [];
foreach ($calendar->events as $event)
{
foreach ($event->tags as $tag)
{
$tags[$tag] = null;
}
}
$result = \array_map(
fn($tag) => [
'id' => $this->hash_tag($tag),
'uri' => $this->encode_tag($tag),
'principaluri' => $principalUri,
'{DAV:}displayname' => $tag,
\sprintf('{%s}supported-calendar-component-set', \Sabre\CalDAV\Plugin::NS_CALDAV) => new \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']),
],
\array_keys($tags)
);
// \error_log(\json_encode($result, \JSON_PRETTY_PRINT));
return $result;
}
/**
* [implementation]
*/
public function createCalendar(
$principalUri,
$calendarUri,
array $properties
)
{
throw (new \Exception('not implemented: createCalendar'));
}
/**
* [implementation]
*/
public function deleteCalendar(
$calendarId
)
{
throw (new \Exception('not implemented: deleteCalendar'));
}
/**
* [implementation]
*/
public function getCalendarObjects(
$calendarId
)
{
$tag = $calendarId;
$calendar = $this->source->get([]);
$result = \array_map(
fn($event) => [
'calendarid' => $calendarId,
'id' => $event->id,
// 'uri' => \sprintf('%s.ics', $entry['id']),
'uri' => $event->id,
'lastmodified' => \time(),
// 'etag' => null,
// 'size' => null,
'component' => 'vevent',
'{DAV:}displayname' => $event->title,
],
\array_values(
\array_filter(
$calendar->events,
fn($event) => \in_array(
$tag,
\array_map(
fn($x) => $this->hash_tag($x),
$event->tags
)
)
)
)
);
return $result;
}
/**
* [implementation]
*/
public function getCalendarObject(
$calendarId,
$objectUri
)
{
$id = $objectUri;
$data = $this->source->get([]);
$entries = \array_values(
\array_filter(
$data,
fn($entry) => ($entry->id === $id)
)
);
if (\count($entries) < 1)
{
throw (new \Exception(\sprintf('not found: %s', $objectUri)));
}
else if (\count($entries) > 1)
{
throw (new \Exception(\sprintf('ambiguous: %s', $objectUri)));
}
else
{
$vcalendar = $this->events_to_vcalendar($entries);
$ics = \davigil\helpers\ics\vcalendar_encode($vcalendar);
return [
'calendardata' => $ics,
'uri' => $objectUri,
/**
* @todo
*/
'lastmodified' => \time(),
/**
* @todo
*/
// 'etag' => '""',
/**
* @todo
*/
// 'size' => 1,
'component' => 'vcalendar',
];
}
}
/**
* [implementation]
*/
public function createCalendarObject(
$calendarId,
$objectUri,
$calendarData
)
{
throw (new \Exception('not implemented: createCalendarObject'));
}
/**
* [implementation]
*/
public function updateCalendarObject(
$calendarId,
$objectUri,
$calendarData
)
{
throw (new \Exception('not implemented: updateCalendarObject'));
}
/**
* [implementation]
*/
public function deleteCalendarObject(
$calendarId,
$objectUri
)
{
throw (new \Exception('not implemented: deleteCalendarObject'));
}
}
?>