send first calendar on ms graph

This commit is contained in:
2022-05-25 21:32:00 +02:00
parent f962b7543f
commit 782436ee2e
13 changed files with 477 additions and 95 deletions

View File

@@ -11,8 +11,12 @@ declare(strict_types=1);
namespace Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph;
use Chill\CalendarBundle\Entity\Calendar;
use Chill\CalendarBundle\Entity\CalendarRange;
use Chill\CalendarBundle\Entity\Invite;
use Chill\CalendarBundle\RemoteCalendar\Model\RemoteEvent;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
use DateTimeImmutable;
use DateTimeZone;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -29,13 +33,16 @@ class RemoteEventConverter
private DateTimeZone $defaultDateTimeZone;
private PersonRenderInterface $personRender;
private DateTimeZone $remoteDateTimeZone;
private TranslatorInterface $translator;
public function __construct(TranslatorInterface $translator)
public function __construct(PersonRenderInterface $personRender, TranslatorInterface $translator)
{
$this->translator = $translator;
$this->personRender = $personRender;
$this->defaultDateTimeZone = (new DateTimeImmutable())->getTimezone();
$this->remoteDateTimeZone = self::getRemoteTimeZone();
}
@@ -71,6 +78,42 @@ class RemoteEventConverter
];
}
public function calendarToEvent(Calendar $calendar): array
{
return [
'subject' => '[Chill] ' .
implode(
', ',
$calendar->getPersons()->map(function (Person $p) {
return $this->personRender->renderString($p, []);
})->toArray()
),
'start' => [
'dateTime' => $calendar->getStartDate()->setTimezone($this->remoteDateTimeZone)
->format(self::REMOTE_DATE_FORMAT),
'timeZone' => 'UTC',
],
'end' => [
'dateTime' => $calendar->getEndDate()->setTimezone($this->remoteDateTimeZone)
->format(self::REMOTE_DATE_FORMAT),
'timeZone' => 'UTC',
],
'allowNewTimeProposals' => false,
'attendees' => $calendar->getInvites()->map(
static function (Invite $i) {
return [
'emailAddress' => [
'address' => $i->getUser()->getEmail(),
'name' => $i->getUser()->getLabel(),
],
'type' => 'Required',
];
}
)->toArray(),
'transactionId' => 'calendar_' . $calendar->getId(),
];
}
public function convertAvailabilityToRemoteEvent(array $event): RemoteEvent
{
$startDate =

View File

@@ -21,6 +21,7 @@ use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteEventConverter;
use Chill\CalendarBundle\Repository\CalendarRangeRepository;
use Chill\MainBundle\Entity\User;
use DateTimeImmutable;
use Exception;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
@@ -137,9 +138,45 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
$this->removeEvent($remoteId, $user);
}
public function syncCalendar(Calendar $calendar, string $action): void
public function syncCalendar(Calendar $calendar, string $action, ?CalendarRange $previousCalendarRange, ?User $previousMainUser, ?array $oldInvites, ?array $newInvites): void
{
// TODO: Implement syncCalendar() method.
/*
* cases to support:
*
* * a calendar range is created:
* * create on remote
* * if calendar range is associated: remove the range
* * a Calendar change the CalendarRange:
* * re-create the previous calendar range;
* * remove the current calendar range
* * a calendar change the mainUser
* * cancel the calendar in the previous mainUser
* * recreate the previous calendar range in the previousMainUser, if any
* * delete the current calendar range in the current mainUser, if any
* * create the calendar in the current mainUser
*
*/
if (!$calendar->hasRemoteId()) {
$this->createCalendarOnRemote($calendar);
} else {
if (null !== $previousMainUser) {
// cancel event in previousMainUserCalendar
// CREATE event in currentMainUser
}
// PATCH event in currentMainUer
}
if ($calendar->hasCalendarRange() && $calendar->getCalendarRange()->hasRemoteId()) {
$this->removeEvent(
$calendar->getCalendarRange()->getRemoteId(),
$calendar->getCalendarRange()->getUser()
);
}
if (null !== $previousCalendarRange) {
// create previousCalendarRange
}
}
public function syncCalendarRange(CalendarRange $calendarRange): void
@@ -151,6 +188,72 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
}
}
private function createCalendarOnRemote(Calendar $calendar): void
{
$eventData = $this->remoteEventConverter->calendarToEvent($calendar);
[
'id' => $id,
'lastModifiedDateTime' => $lastModified,
'changeKey' => $changeKey
] = $this->createOnRemote($eventData, $calendar->getMainUser(), 'calendar_' . $calendar->getId());
if (null === $id) {
return;
}
$calendar
->setRemoteId($id)
->addRemoteAttributes([
'lastModifiedDateTime' => $lastModified,
'changeKey' => $changeKey,
]);
}
/**
* @param string $identifier an identifier for logging in case of something does not work
*
* @return array{?id: string, ?lastModifiedDateTime: int, ?changeKey: string}
*/
private function createOnRemote(array $eventData, User $user, string $identifier): array
{
$userId = $this->mapCalendarToUser->getUserId($user);
if (null === $userId) {
$this->logger->warning('user does not have userId nor calendarId', [
'user_id' => $user->getId(),
'calendar_identifier' => $identifier,
]);
return [];
}
dump($eventData);
try {
$event = $this->machineHttpClient->request(
'POST',
'users/' . $userId . '/calendar/events',
[
'json' => $eventData,
]
)->toArray();
} catch (ClientExceptionInterface $e) {
$this->logger->warning('could not save calendar range to remote', [
'exception' => $e->getTraceAsString(),
'content' => $e->getResponse()->getContent(),
'calendar_identifier' => $identifier,
]);
throw $e;
}
return [
'id' => $event['id'],
'lastModifiedDateTime' => $this->remoteEventConverter->getLastModifiedDate($event)->getTimestamp(),
'changeKey' => $event['changeKey'],
];
}
private function createRemoteCalendarRange(CalendarRange $calendarRange): void
{
$userId = $this->mapCalendarToUser->getUserId($calendarRange->getUser());
@@ -191,6 +294,31 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
]);
}
private function getOnRemote(User $user, string $remoteId): array
{
$userId = $this->mapCalendarToUser->getUserId($user);
if (null === $userId) {
throw new Exception('no remote calendar for this user', [
'user' => $user->getId(),
'remoteId' => $remoteId,
]);
}
try {
return $this->machineHttpClient->request(
'GET',
'users/' . $userId . '/calendar/events/' . $remoteId
)->toArray();
} catch (ClientExceptionInterface $e) {
$this->logger->warning('Could not get event from calendar', [
'remoteId' => $remoteId,
]);
throw $e;
}
}
private function getScheduleTimesForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): array
{
$userId = $this->mapCalendarToUser->getUserId($user);
@@ -236,6 +364,48 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
);
}
/**
* @param string $identifier an identifier for logging in case of something does not work
*
* @return array{?id: string, ?lastModifiedDateTime: int, ?changeKey: string}
*/
private function patchOnRemote(string $remoteId, array $eventData, User $user, string $identifier): array
{
$userId = $this->mapCalendarToUser->getUserId($user);
if (null === $userId) {
$this->logger->warning('user does not have userId nor calendarId', [
'user_id' => $user->getId(),
'calendar_identifier' => $identifier,
]);
return [];
}
try {
$event = $this->machineHttpClient->request(
'PATCH',
'users/' . $userId . '/calendar/events/' . $remoteId,
[
'json' => $eventData,
]
)->toArray();
} catch (ClientExceptionInterface $e) {
$this->logger->warning('could not update calendar range to remote', [
'exception' => $e->getTraceAsString(),
'calendarRangeId' => $identifier,
]);
throw $e;
}
return [
'id' => $event['id'],
'lastModifiedDateTime' => $this->remoteEventConverter->getLastModifiedDate($event)->getTimestamp(),
'changeKey' => $event['changeKey'],
];
}
private function removeEvent($remoteId, User $user): void
{
$userId = $this->mapCalendarToUser->getUserId($user);

View File

@@ -39,7 +39,7 @@ class NullRemoteCalendarConnector implements RemoteCalendarConnectorInterface
{
}
public function syncCalendar(Calendar $calendar, string $action): void
public function syncCalendar(Calendar $calendar, string $action, ?CalendarRange $previousCalendarRange, ?User $previousMainUser, ?array $oldInvites, ?array $newInvites): void
{
}

View File

@@ -40,7 +40,10 @@ interface RemoteCalendarConnectorInterface
public function removeCalendarRange(string $remoteId, array $remoteAttributes, User $user): void;
public function syncCalendar(Calendar $calendar, string $action): void;
/**
* @param array<array{inviteId: int, userId: int, userEmail: int, userLabel: string}> $oldInvites
*/
public function syncCalendar(Calendar $calendar, string $action, ?CalendarRange $previousCalendarRange, ?User $previousMainUser, ?array $oldInvites, ?array $newInvites): void;
public function syncCalendarRange(CalendarRange $calendarRange): void;
}