0
0
Fork 0
mirror of https://github.com/nextcloud/server.git synced 2025-01-31 06:43:12 +00:00
nextcloud_server/lib/private/Calendar/CalendarEventBuilder.php
Richard Steinmetz 80bc1c2d6c
feat(ocp): calendar event builder api
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
2025-01-06 10:16:53 +01:00

132 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Calendar;
use DateTimeInterface;
use InvalidArgumentException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Calendar\ICalendarEventBuilder;
use OCP\Calendar\ICreateFromString;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\Component\VEvent;
class CalendarEventBuilder implements ICalendarEventBuilder {
private ?DateTimeInterface $startDate = null;
private ?DateTimeInterface $endDate = null;
private ?string $summary = null;
private ?string $description = null;
private ?string $location = null;
private ?array $organizer = null;
private array $attendees = [];
public function __construct(
private readonly string $uid,
private readonly ITimeFactory $timeFactory,
) {
}
public function setStartDate(DateTimeInterface $start): ICalendarEventBuilder {
$this->startDate = $start;
return $this;
}
public function setEndDate(DateTimeInterface $end): ICalendarEventBuilder {
$this->endDate = $end;
return $this;
}
public function setSummary(string $summary): ICalendarEventBuilder {
$this->summary = $summary;
return $this;
}
public function setDescription(string $description): ICalendarEventBuilder {
$this->description = $description;
return $this;
}
public function setLocation(string $location): ICalendarEventBuilder {
$this->location = $location;
return $this;
}
public function setOrganizer(string $email, ?string $commonName = null): ICalendarEventBuilder {
$this->organizer = [$email, $commonName];
return $this;
}
public function addAttendee(string $email, ?string $commonName = null): ICalendarEventBuilder {
$this->attendees[] = [$email, $commonName];
return $this;
}
public function toIcs(): string {
if ($this->startDate === null) {
throw new InvalidArgumentException('Event is missing a start date');
}
if ($this->endDate === null) {
throw new InvalidArgumentException('Event is missing an end date');
}
if ($this->summary === null) {
throw new InvalidArgumentException('Event is missing a summary');
}
if ($this->organizer === null && $this->attendees !== []) {
throw new InvalidArgumentException('Event has attendees but is missing an organizer');
}
$vcalendar = new VCalendar();
$props = [
'UID' => $this->uid,
'DTSTAMP' => $this->timeFactory->now(),
'SUMMARY' => $this->summary,
'DTSTART' => $this->startDate,
'DTEND' => $this->endDate,
];
if ($this->description !== null) {
$props['DESCRIPTION'] = $this->description;
}
if ($this->location !== null) {
$props['LOCATION'] = $this->location;
}
/** @var VEvent $vevent */
$vevent = $vcalendar->add('VEVENT', $props);
if ($this->organizer !== null) {
self::addAttendeeToVEvent($vevent, 'ORGANIZER', $this->organizer);
}
foreach ($this->attendees as $attendee) {
self::addAttendeeToVEvent($vevent, 'ATTENDEE', $attendee);
}
return $vcalendar->serialize();
}
public function createInCalendar(ICreateFromString $calendar): string {
$fileName = $this->uid . '.ics';
$calendar->createFromString($fileName, $this->toIcs());
return $fileName;
}
/**
* @param array{0: string, 1: ?string} $tuple A tuple of [$email, $commonName] where $commonName may be null.
*/
private static function addAttendeeToVEvent(VEvent $vevent, string $name, array $tuple): void {
[$email, $cn] = $tuple;
if (!str_starts_with($email, 'mailto:')) {
$email = "mailto:$email";
}
$params = [];
if ($cn !== null) {
$params['CN'] = $cn;
}
$vevent->add($name, $email, $params);
}
}