30 public const CREATE_PATH =
'/calendars/%CALENDAR_ID%/events/';
31 public const EVENT_PATH =
'/calendars/%CALENDAR_ID%/events/%EVENT_ID%';
52 $this->httpClient->post(
54 $this->encode($converter->convertForCreate())
57 if ($this->isRequestSuccess())
59 $requestResult = $this->prepareResult($this->httpClient->getResult(),
$event);
61 $result->setData($requestResult);
65 $response = Json::decode($this->httpClient->getResult());
69 switch ($error[
'code'])
74 $this->handleUnauthorize($this->connection);
75 $result->addError(
new Error($error[
'message'], $error[
'code']));
78 if (!empty($error[
'code']))
80 $result->addError(
new Error($error[
'message'], $error[
'code']));
84 $result->addError(
new Error(
'Uncknown Google API error', 400));
99 $result->addError(
new Error($e->getMessage(), $e->getCode()));
103 $result->addError(
new Error(
'failed to create an event in google'));
107 $result->addError(
new Error(
'failed to convert event'));
133 eventConnection:
$context->getEventConnection(),
135 $this->httpClient->query(
136 HttpClient::HTTP_PUT,
138 $this->encode($converter->convertForUpdate())
141 if ($this->isRequestSuccess())
143 $requestResult = $this->prepareResult($this->httpClient->getResult(),
$event);
145 if ($childList = (
$context->sync[
'childList'] ??
null))
151 foreach ($childList as $eventId => $childEvent)
153 $childResult = $this->createInstance($childEvent,
$context);
154 if ($childResult->isSuccess())
156 $data = $childResult->getData()[
'event'];
159 $link = $mapper->getMap([
160 '=EVENT_ID' => $childEvent->getId(),
161 '=CONNECTION_ID' => $this->connection->getId(),
166 ->setVendorEventId(
$data[
'id'])
167 ->setEntityTag(
$data[
'etag'])
168 ->setVendorVersionId(
$data[
'version'])
169 ->setRecurrenceId($requestResult[
'event'][
'id'])
171 $mapper->update($link);
176 $result->setData($requestResult);
180 $response = Json::decode($this->httpClient->getResult());
183 $this->handleUnauthorize($this->connection);
188 $result->addError(
new Error(
'error of updating event', $this->httpClient->getStatus()));
192 catch (ArgumentException $e)
194 $result->addError(
new Error(
'failed to update an event in google'));
196 catch (ObjectException $e)
198 $result->addError(
new Error(
'failed to convert event'));
222 $this->httpClient->query(
223 HttpClient::HTTP_DELETE,
225 $this->encode($converter->convertForDelete())
228 if ($this->isRequestDeleteSuccess())
230 if (
$response = $this->httpClient->getResult())
232 $requestResult = Json::decode(
$response);
233 $result->setData($requestResult);
238 $response = Json::decode($this->httpClient->getResult());
241 $this->handleUnauthorize($this->connection);
246 $result->addError(
new Error(
'error of deleting event'));
253 $result->addError(
new Error(
'failed to delete an event in google'));
257 $result->addError(
new Error(
'failed to convert event'));
273 if ($instanceContext ===
null)
275 return $result->addError(
new Error(
'failed to create an instance in google'));
285 eventConnection: $instanceContext->getEventConnection()
287 $this->httpClient->query(
288 HttpClient::HTTP_PUT,
290 $this->encode($converter->convertForUpdate())
293 if ($this->isRequestSuccess())
295 $requestResult = $this->prepareResult($this->httpClient->getResult(),
$event);
297 $result->setData($requestResult);
301 $response = Json::decode($this->httpClient->getResult());
304 $this->handleUnauthorize($this->connection);
309 $result->addError(
new Error(
'error of creating instance'));
315 $result->addError(
new Error(
'failed to create an instance in google'));
327 $eventLink =
$context->sync[
'instanceLink'];
332 ->setSectionConnection(
$context->getSectionConnection())
333 ->setEventConnection($eventLink)
337 if (!
$result->isSuccess() &&
$result->getErrorCollection()->getErrorByCode(403))
345 return (
new Result())->addError(
new Error(
'Not found link for instance'));
360 $excludeDate =
$context->sync[
'excludeDate'] ??
null;
361 $originalDate =
$context->sync[
'originalDate'] ??
null;
366 if ($instanceContext ===
null)
368 return $result->addError(
new Error(
'failed to delete an instance in google'));
375 eventConnection: $instanceContext->getEventConnection()
377 $this->httpClient->query(
378 HttpClient::HTTP_PUT,
380 $this->encode($converter->convertForDeleteInstance())
383 if ($this->isRequestSuccess())
385 $requestResult = $this->prepareResult($this->httpClient->getResult(),
$event);
387 $result->setData($requestResult);
391 $response = Json::decode($this->httpClient->getResult());
394 $this->handleUnauthorizeException();
397 $result->addError(
new Error(
'error of delete instance'));
403 $result->addError(
new Error(
'failed to delete an instance in google'));
415 return Server::mapUri(
416 $this->connection->getServer()->getFullPath() . self::CREATE_PATH,
418 '%CALENDAR_ID%' => Server::getEncodePath(
$context->getSectionConnection()->getVendorSectionId()),
430 return Server::mapUri(
431 $this->connection->getServer()->getFullPath() . self::EVENT_PATH,
433 '%CALENDAR_ID%' => Server::getEncodePath(
$context->getSectionConnection()->getVendorSectionId()),
434 '%EVENT_ID%' => Server::getEncodePath(
$context->getEventConnection()->getVendorEventId()),
449 public function saveRecurrence(
457 if ($recurrenceEvent->getEventConnection())
459 $masterResult = $this->updateRecurrenceEntity($recurrenceEvent,
$context);
463 $masterResult = $this->createRecurrenceEntity($recurrenceEvent, $sectionConnection,
$context);
466 if (!$masterResult->isSuccess())
468 $result->addErrors($masterResult->getErrors());
472 if ($recurrenceEvent->getInstanceMap())
475 foreach ($recurrenceEvent->getInstanceMap()->getCollection() as
$instance)
479 $instanceResult = $this->updateRecurrenceEntity(
$instance,
$context, $recurrenceEvent->getEventConnection());
483 $instanceResult = $this->createRecurrenceEntity(
487 $recurrenceEvent->getEventConnection()
493 $result->addErrors($instanceResult->getErrors());
517 return $this->saveRecurrence($recurrenceEvent, $sectionConnection,
$context);
536 return $this->saveRecurrence($recurrenceEvent, $sectionConnection,
$context);
549 (
$context->getEventConnection() ===
null)
550 || (
$context->getSectionConnection() ===
null)
556 $masterVendorEventId =
$context->getEventConnection()->getVendorEventId();
558 if (
$context->getEventConnection()->getEvent()->getVersion() >
$event->getVersion())
560 $event->setVersion(
$context->getEventConnection()->getEvent()->getVersion());
564 ->setSectionConnection(
$context->getSectionConnection())
565 ->setEventConnection(
568 $this->getInstanceId($masterVendorEventId,
$event)
570 ->setRecurrenceId($masterVendorEventId)
580 private function getInstanceId(
string $masterId,
Event $event): string
582 $base = $masterId .
'_';
583 if (
$event->isFullDayEvent())
605 $instanceEvent = clone
$event;
607 $instanceEvent->getStart()->getDate()->setDate(
608 $excludeDate->getYear(),
609 $excludeDate->getMonth(),
610 $excludeDate->getDay()
612 $instanceEvent->getEnd()->getDate()->setDate(
613 $excludeDate->getYear(),
614 $excludeDate->getMonth(),
615 $excludeDate->getDay()
618 ->setOriginalDateFrom($originalDate ??
$event->getStart())
619 ->setRecurringRule(
null)
622 return $instanceEvent;
636 private function createRecurrenceEntity(
646 $eventContext->setSectionConnection($sectionConnection);
650 $eventContext->setEventConnection($masterLink);
651 $result = $this->createInstance($syncEvent->getEvent(), $eventContext);
655 $result = $this->create($syncEvent->getEvent(), $eventContext);
660 if (!$syncEvent->getEvent()->isDeleted())
662 $link = (
new EventConnection())
663 ->setEvent($syncEvent->getEvent())
664 ->setConnection($sectionConnection->getConnection())
665 ->setVersion($syncEvent->getEvent()->getVersion())
666 ->setVendorEventId(
$result->getData()[
'event'][
'id'])
667 ->setEntityTag(
$result->getData()[
'event'][
'etag'])
669 $syncEvent->setEventConnection($link);
673 $syncEvent->setAction(Dictionary::SYNC_EVENT_ACTION[
'delete']);
689 private function updateRecurrenceEntity(
690 SyncEvent $syncEvent,
692 EventConnection $masterLink =
null
695 $eventContext =
new EventContext();
699 $eventContext->setEventConnection($masterLink);
704 $eventContext->setEventConnection($syncEvent->getEventConnection());
705 $result = $this->
update($syncEvent->getEvent(), $eventContext);
709 $syncEvent->getEventConnection()->setEntityTag(
$result->getData()[
'event'][
'etag']);
720 return Json::encode(
$event, JSON_UNESCAPED_SLASHES);
733 $externalEvent = Json::decode(
$result);
743 'id' => $externalEvent[
'id'],
744 'etag' => $externalEvent[
'etag'],
745 'version' => $externalEvent[
'etag'],
746 'recurrence' => $externalEvent[
'recurringEventId'] ??
null,
750 private function handleUnauthorizeException()
752 $this->handleUnauthorize($this->connection);