calendar range: update on remote after an unpdate

This commit is contained in:
Julien Fastré 2022-05-11 14:20:41 +02:00
parent c892f7de7b
commit dd13e631ac
3 changed files with 82 additions and 14 deletions

View File

@ -15,6 +15,14 @@ use Doctrine\ORM\Mapping as ORM;
trait RemoteCalendarTrait trait RemoteCalendarTrait
{ {
/**
* If true, the changes won't be enqueued to remote.
*
* This is required to prevent update loop: a persist trigger an event creation on remote,
* which in turn change remoteId and, in turn, trigger an update change, ...
*/
public bool $preventEnqueueChanges = false;
/** /**
* @ORM\Column(type="json", options={"default": "[]"}, nullable=false) * @ORM\Column(type="json", options={"default": "[]"}, nullable=false)
*/ */
@ -25,14 +33,6 @@ trait RemoteCalendarTrait
*/ */
private string $remoteId = ''; private string $remoteId = '';
/**
* If true, the changes won't be enqueued to remote
*
* This is required to prevent update loop: a persist trigger an event creation on remote,
* which in turn change remoteId and, in turn, trigger an update change, ...
*/
public bool $preventEnqueueChanges = false;
public function addRemoteAttributes(array $remoteAttributes): self public function addRemoteAttributes(array $remoteAttributes): self
{ {
$this->remoteAttributes = array_merge($this->remoteAttributes, $remoteAttributes); $this->remoteAttributes = array_merge($this->remoteAttributes, $remoteAttributes);

View File

@ -107,6 +107,11 @@ class RemoteEventConverter
); );
} }
public function getLastModifiedDate(array $event): DateTimeImmutable
{
return DateTimeImmutable::createFromFormat(self::REMOTE_DATETIMEZONE_FORMAT, $event['lastModifiedDateTime']);
}
/** /**
* Return a string which format a DateTime to string. To be used in POST requests,. * Return a string which format a DateTime to string. To be used in POST requests,.
*/ */

View File

@ -19,7 +19,6 @@ use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\OnBehalfOfUserTokenSto
use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteEventConverter; use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\RemoteEventConverter;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use DateTimeImmutable; use DateTimeImmutable;
use Exception;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
@ -110,10 +109,11 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
public function syncCalendarRange(CalendarRange $calendarRange): void public function syncCalendarRange(CalendarRange $calendarRange): void
{ {
if ($calendarRange->hasRemoteId()) { if ($calendarRange->hasRemoteId()) {
throw new Exception('update existing not implemented'); $this->updateRemoteCalendarRange($calendarRange);
} } else {
$this->createRemoteCalendarRange($calendarRange); $this->createRemoteCalendarRange($calendarRange);
} }
}
private function createRemoteCalendarRange(CalendarRange $calendarRange): void private function createRemoteCalendarRange(CalendarRange $calendarRange): void
{ {
@ -148,11 +148,9 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
throw $e; throw $e;
} }
dump($event);
$calendarRange->setRemoteId($event['id']) $calendarRange->setRemoteId($event['id'])
->addRemoteAttributes([ ->addRemoteAttributes([
'lastModifiedDateTime' => (DateTimeImmutable::createFromFormat(RemoteEventConverter::REMOTE_DATETIMEZONE_FORMAT, $event['lastModifiedDateTime']))->getTimestamp(), 'lastModifiedDateTime' => $this->remoteEventConverter->getLastModifiedDate($event)->getTimestamp(),
'changeKey' => $event['changeKey'], 'changeKey' => $event['changeKey'],
]); ]);
} }
@ -201,4 +199,69 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
$response['value'][0]['scheduleItems'] $response['value'][0]['scheduleItems']
); );
} }
private function updateRemoteCalendarRange(CalendarRange $calendarRange): void
{
$userId = $this->mapCalendarToUser->getUserId($calendarRange->getUser());
$calendarId = $this->mapCalendarToUser->getCalendarId($calendarRange->getUser());
if (null === $userId || null === $calendarId) {
$this->logger->warning('user does not have userId nor calendarId', [
'user_id' => $calendarRange->getUser()->getId(),
'calendar_range_id' => $calendarRange->getId(),
]);
return;
}
try {
$event = $this->machineHttpClient->request(
'GET',
'users/' . $userId . '/calendar/events/' . $calendarRange->getRemoteId()
)->toArray();
} catch (ClientExceptionInterface $e) {
$this->logger->warning('Could not get event from calendar', [
'calendar_range_id' => $calendarRange->getId(),
'calendar_range_remote_id' => $calendarRange->getRemoteId(),
]);
throw $e;
}
if ($this->remoteEventConverter->getLastModifiedDate($event)->getTimestamp() > $calendarRange->getUpdatedAt()->getTimestamp()) {
$this->logger->info('Skip updating as the lastModified date seems more fresh than the database one', [
'calendar_range_id' => $calendarRange->getId(),
'calendar_range_remote_id' => $calendarRange->getRemoteId(),
'db_last_updated' => $calendarRange->getUpdatedAt()->getTimestamp(),
'remote_last_updated' => $this->remoteEventConverter->getLastModifiedDate($event)->getTimestamp(),
]);
return;
}
$eventData = $this->remoteEventConverter->calendarRangeToEvent($calendarRange);
try {
$event = $this->machineHttpClient->request(
'PATCH',
'users/' . $userId . '/calendar/events/' . $calendarRange->getRemoteId(),
[
'json' => $eventData,
]
)->toArray();
} catch (ClientExceptionInterface $e) {
$this->logger->warning('could not update calendar range to remote', [
'exception' => $e->getTraceAsString(),
'calendarRangeId' => $calendarRange->getId(),
]);
throw $e;
}
$calendarRange
->addRemoteAttributes([
'lastModifiedDateTime' => $this->remoteEventConverter->getLastModifiedDate($event)->getTimestamp(),
'changeKey' => $event['changeKey'],
]);
}
} }