<?php
namespace App\Service;
use App\Entity\Child;
use App\Entity\Guardian;
use App\Entity\Lesson;
use App\Entity\Teacher;
use Doctrine\ORM\EntityManagerInterface;
use Google_Client;
use Google_Service_Calendar;
use Google_Service_Calendar_Event;
use Google_Service_Calendar_EventDateTime;
use Google_Service_Exception;
use Psr\Container\ContainerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class GoogleCalendarService
{
private $client;
private EntityManagerInterface $entityManager;
private $user = null;
private UrlGeneratorInterface $urlGenerator;
private ContainerInterface $container;
public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, ContainerInterface $container)
{
$this->client = new Google_Client();
$this->client->setClientId($_ENV['GOOGLE_ID']);
$this->client->setClientSecret($_ENV['GOOGLE_SECRET']);
$this->client->addScope('https://www.googleapis.com/auth/calendar');
$this->client->addScope('https://www.googleapis.com/auth/calendar.events');
// $this->client->addScope(Google_Service_Calendar::CALENDAR);
$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->container = $container;
}
public function authenticate($authCode)
{
$accessToken = $this->client->fetchAccessTokenWithAuthCode($authCode);
$this->client->setAccessToken($accessToken);
return $accessToken;
}
public function setAccessToken($accessToken)
{
$this->client->setAccessToken($accessToken);
}
public function setUser($user)
{
$this->client = new Google_Client();
$this->client->setClientId($_ENV['GOOGLE_ID']);
$this->client->setClientSecret($_ENV['GOOGLE_SECRET']);
$this->client->addScope('https://www.googleapis.com/auth/calendar');
$this->client->addScope('https://www.googleapis.com/auth/calendar.events');
if (!$user->getGoogleAccessToken()) {
$this->user = null;
}
$this->user = $user;
$this->client->setAccessToken($user->getGoogleAccessToken());
if ($this->client->isAccessTokenExpired()) {
// Refresh the token if it's expired
$refreshToken = $user->getGoogleRefreshToken();
if ($refreshToken) {
$this->client->fetchAccessTokenWithRefreshToken($refreshToken);
$newAccessToken = $this->client->getAccessToken();
$user->setGoogleAccessToken($newAccessToken);
$this->client->setAccessToken($newAccessToken);
$this->entityManager->persist($user);
$this->entityManager->flush();
} else {
$this->user = null;
}
}
}
public function manageLessonEvent(Lesson $lesson)
{
try {
if ($this->user instanceof Teacher) {
if (!$lesson->getGoogleCalendarIdTeacher()) {
$calendarId = 'primary';
// dump('event create');
$response = $this->createEvent($calendarId, $this->formatLessonEvent($lesson));
if($response) {
$lesson->setGoogleCalendarIdTeacher($response->getId());
}
$this->entityManager->persist($lesson);
$this->entityManager->flush();
if($lesson->getGoogleCalendarIdTeacher()) {
$this->checkForDuplicates($lesson, $lesson->getGoogleCalendarIdTeacher());
}
} else {
$calendarId = 'primary';
$response = $this->updateEvent($calendarId, $lesson->getGoogleCalendarIdTeacher(), $this->formatLessonEvent($lesson));
// dump($response);
// die();
if($response) {
$lesson->setGoogleCalendarIdTeacher($response->getId());
}
$this->entityManager->persist($lesson);
$this->entityManager->flush();
if($lesson->getGoogleCalendarIdTeacher()) {
$this->checkForDuplicates($lesson, $lesson->getGoogleCalendarIdTeacher());
}
}
}
if ($this->user instanceof Child) {
if (!$lesson->getGoogleCalendarIdChild()) {
$calendarId = 'primary';
$response = $this->createEvent($calendarId, $this->formatLessonEvent($lesson));
if($response) {
$lesson->setGoogleCalendarIdChild($response->getId());
}
$this->entityManager->persist($lesson);
$this->entityManager->flush();
if($lesson->getGoogleCalendarIdChild()) {
$this->checkForDuplicates($lesson, $lesson->getGoogleCalendarIdChild());
}
} else {
$calendarId = 'primary';
$response = $this->updateEvent($calendarId, $lesson->getGoogleCalendarIdChild(), $this->formatLessonEvent($lesson));
if($response) {
$lesson->setGoogleCalendarIdChild($response->getId());
}
$this->entityManager->persist($lesson);
$this->entityManager->flush();
if($lesson->getGoogleCalendarIdChild()) {
$this->checkForDuplicates($lesson, $lesson->getGoogleCalendarIdChild());
}
}
}
if ($this->user instanceof Guardian) {
if (!$lesson->getGoogleCalendarIdGuardian()) {
$calendarId = 'primary';
$response = $this->createEvent($calendarId, $this->formatLessonEvent($lesson));
if($response) {
$lesson->setGoogleCalendarIdGuardian($response->getId());
}
$this->entityManager->persist($lesson);
$this->entityManager->flush();
if($lesson->getGoogleCalendarIdGuardian()) {
$this->checkForDuplicates($lesson, $lesson->getGoogleCalendarIdGuardian());
}
} else {
$calendarId = 'primary';
$response = $this->updateEvent($calendarId, $lesson->getGoogleCalendarIdGuardian(), $this->formatLessonEvent($lesson));
if($response) {
$lesson->setGoogleCalendarIdGuardian($response->getId());
}
$this->entityManager->persist($lesson);
$this->entityManager->flush();
if($lesson->getGoogleCalendarIdGuardian()) {
$this->checkForDuplicates($lesson, $lesson->getGoogleCalendarIdGuardian());
}
}
}
} catch (\Exception $e) {
return null;
}
}
public function formatLessonEvent(Lesson $lesson)
{
if ($this->user instanceof Teacher) {
$child = $lesson->getChild();
$name = '';
if ($child) {
$name = $child->getFullname();
}
$summary = "{$lesson->getDiscipline()->getName()} - {$lesson->getClass()} - {$name} | COREPETITUS";
$location = "https://app.corepetitus.lt";
}
if ($this->user instanceof Child || $this->user instanceof Guardian) {
$summary = "{$lesson->getDiscipline()->getName()} - {$lesson->getClass()} - {$lesson->getTeacher()->getFullname()} | COREPETITUS";
$location = $this->container->getParameter('domain') . $this->urlGenerator->generate('unicko_public_router', ['token' => $lesson->getPublicToken()]);
}
$event = [
'status' => "confirmed",
'summary' => $summary,
'location' => $location,
'start' => new Google_Service_Calendar_EventDateTime([
'dateTime' => $lesson->getStartTime()->format(\DateTime::RFC3339),
'timeZone' => 'Europe/Vilnius',
]),
'end' => new Google_Service_Calendar_EventDateTime([
'dateTime' => $lesson->getEndTime()->format(\DateTime::RFC3339),
'timeZone' => 'Europe/Vilnius',
]),
];
return $event;
}
public function createEvent($calendarId = 'primary', $eventData)
{
$service = new Google_Service_Calendar($this->client);
$event = new Google_Service_Calendar_Event($eventData);
try {
return $service->events->insert($calendarId, $event);
} catch (\Exception $e) {
return null;
}
}
public function updateEvent($calendarId = 'primary', $eventId, $eventData)
{
$service = new Google_Service_Calendar($this->client);
$event = $service->events->get($calendarId, $eventId);
foreach ($eventData as $key => $value) {
$event->$key = $value;
}
try {
return $service->events->update($calendarId, $event->getId(), $event);
} catch (\Exception $e) {
return null;
}
}
public function deleteEvent($calendarId = 'primary', $eventId)
{
$service = new Google_Service_Calendar($this->client);
try {
return $service->events->delete($calendarId, $eventId);
} catch (\Exception $e) {
return null;
}
}
public function checkForDuplicates($lesson,$googleCalendarId)
{
$calendarId = 'primary';
$service = new Google_Service_Calendar($this->client);
$summary = '';
if ($this->user instanceof Teacher) {
$child = $lesson->getChild();
$name = '';
if ($child) {
$name = $child->getFullname();
}
$summary = "{$lesson->getDiscipline()->getName()} - {$lesson->getClass()} - {$name} | COREPETITUS";
}
if ($this->user instanceof Child || $this->user instanceof Guardian) {
$summary = "{$lesson->getDiscipline()->getName()} - {$lesson->getClass()} - {$lesson->getTeacher()->getFullname()} | COREPETITUS";
}
if ($this->user instanceof Teacher) {
try {
$events = $service->events->listEvents($calendarId, [
'q' => "https://app.corepetitus.lt",
'timeMin' => $lesson->getStartTime()->format(\DateTime::RFC3339),
'timeMax' => $lesson->getEndTime()->format(\DateTime::RFC3339),
]);
$items = $events->getItems();
if ($items > 1) {
foreach ($items as $item) {
if ($item->getId() != $googleCalendarId && $item->getLocation() == 'https://app.corepetitus.lt' && $item->getSummary() == $summary) {
$this->deleteEvent($calendarId, $item->getId());
}
}
}
} catch (\Exception $e) {
return null;
}
}
if ($this->user instanceof Child or $this->user instanceof Guardian) {
try {
$events = $service->events->listEvents($calendarId, [
'q' => "https://app.corepetitus.lt/pamoka/{$lesson->getPublicToken()}",
'timeMin' => $lesson->getStartTime()->format(\DateTime::RFC3339),
'timeMax' => $lesson->getEndTime()->format(\DateTime::RFC3339),
]);
$items = $events->getItems();
if ($items > 1) {
foreach ($items as $item) {
if ($item->getId() != $googleCalendarId && $item->getSummary() == $summary) {
$this->deleteEvent($calendarId, $item->getId());
}
}
}
} catch (\Exception $e) {
return null;
}
}
}
public function deleteEverything()
{
$calendarId = 'primary';
$service = new Google_Service_Calendar($this->client);
try {
$events = $service->events->listEvents($calendarId, [
'q' => "https://app.corepetitus.lt",
]);
$items = $events->getItems();
foreach ($items as $item) {
$this->deleteEvent($calendarId, $item->getId());
usleep(500000);
}
} catch (\Exception $e) {
return null;
}
}
}