suivi/src/Webdav/CaldavClient.php

124 lines
3.2 KiB
PHP

<?php
namespace App\Webdav;
use Sabre\DAV\Client;
/**
* class CaldavClient.
*
* @author Simon Vieille <simon@deblan.fr>
*/
class CaldavClient
{
protected string $host;
protected string $username;
protected string $password;
protected ?Client $client = null;
public function __construct(string $host, string $username, string $password)
{
$this->host = $host;
$this->username = $username;
$this->password = $password;
}
protected function getClient(): Client
{
if (null === $this->client) {
$this->client = new Client([
'baseUri' => $this->host,
'userName' => $this->username,
'password' => $this->password,
]);
}
return $this->client;
}
public function getEvents(string $calendarUri)
{
$body = '<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
<d:prop>
<d:getetag />
<c:calendar-data />
</d:prop>
<c:filter>
<c:comp-filter name="VCALENDAR">
</c:comp-filter>
</c:filter>
</c:calendar-query>';
$response = $this->getClient()->request(
'REPORT',
$calendarUri,
$body,
[
'Depth' => 1,
'Prefer' => 'return-minimal',
'Content-Type' => 'application/xml; charset=utf-8',
]
);
$body = $response['body'];
$events = [];
preg_match_all('#<cal:calendar-data>(.+)</cal:calendar-data>#isU', $body, $rawEvents, PREG_SET_ORDER);
foreach ($rawEvents as $rawEvent) {
$events[] = $this->createEvent($rawEvent[1]);
}
return $events;
}
protected function createEvent(string $rawEvent): Event
{
preg_match_all('/
^([A-Z\-]+)[:;]{1}([^\n]+)\n
((\ [^\n]+\n)*\3*)
/xm', $rawEvent, $matches, PREG_SET_ORDER);
$datas = [];
foreach ($matches as $match) {
$key = $match[1];
if (isset($datas[$key])) {
continue;
}
$lines = array_map(fn ($line) => trim($line), explode("\n", $match[2].$match[3]));
$lines = str_replace('\\n', "\n", implode('', $lines));
if (in_array($key, ['DTSTART', 'DTEND'])) {
if (empty($lines)) {
continue;
}
@list($tz, $time) = explode(':', $lines);
if (empty($time)) {
continue;
}
$lines = new \DateTime($time);
}
$datas[$key] = $lines;
}
$event = new Event();
$event
->setUid($datas['UID'])
->setSummary($datas['SUMMARY'] ?? null)
->setDescription($datas['DESCRIPTION'] ?? null)
->setLocation($datas['LOCATION'] ?? null)
->setSummary($datas['SUMMARY'] ?? null)
->setStartAt($datas['DTSTART'] ?? null)
->setFinishAt($datas['DTEND'] ?? null)
;
return $event;
}
}