src/EventSubscriber/CreateZoomMeetingSubscriber.php line 122

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Harmonizely\EventSubscriber;
  4. use DateTimeZone;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use Harmonizely\CalendarEvents;
  7. use Harmonizely\EventTypes\LocationTypeProvider;
  8. use Harmonizely\Integration\Provider\ZoomClientProviderInterface;
  9. use Harmonizely\Integration\Zoom\Exception\CouldNotUpdateZoomMeetingException;
  10. use Harmonizely\Model\EventInterface;
  11. use Harmonizely\Model\EventTypeInterface;
  12. use Harmonizely\Model\Integration;
  13. use Harmonizely\Model\IntegrationInterface;
  14. use Harmonizely\Model\UserInterface;
  15. use Harmonizely\Types\Company\IntegrationType;
  16. use Psr\Log\LoggerInterface;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. use Symfony\Component\EventDispatcher\GenericEvent;
  19. use Webmozart\Assert\Assert;
  20. final class CreateZoomMeetingSubscriber implements EventSubscriberInterface
  21. {
  22.     private $zoomClientProvider;
  23.     private $entityManager;
  24.     private $logger;
  25.     private LocationTypeProvider $locationTypeProvider;
  26.     public function __construct(
  27.         ZoomClientProviderInterface $zoomClientProvider,
  28.         EntityManagerInterface $entityManager,
  29.         LoggerInterface $logger,
  30.         LocationTypeProvider $locationTypeProvider
  31.     ) {
  32.         $this->zoomClientProvider $zoomClientProvider;
  33.         $this->entityManager $entityManager;
  34.         $this->logger $logger;
  35.         $this->locationTypeProvider $locationTypeProvider;
  36.     }
  37.     public static function getSubscribedEvents(): array
  38.     {
  39.         return [
  40.             CalendarEvents::EVENT_PRE_CREATE => 'createMeeting',
  41.             CalendarEvents::EVENT_POST_CANCEL => 'cancelMeeting',
  42.             CalendarEvents::EVENT_POST_RESCHEDULE => 'updateMeeting',
  43.         ];
  44.     }
  45.     public function createMeeting(GenericEvent $event): void
  46.     {
  47.         /** @var EventInterface $event */
  48.         $event $event->getSubject();
  49.         Assert::isInstanceOf($eventEventInterface::class);
  50.         $eventType $event->getEventType();
  51.         $user $event->getUser();
  52.         $locationType $this->locationTypeProvider->provideFor($eventType$user$event);
  53.         $integration $this->findIntegration($user);
  54.         if (null === $integration || EventTypeInterface::LOCATION_TYPE_ZOOM !== $locationType) {
  55.             return;
  56.         }
  57.         if (!$integration->isEnabled()) {
  58.             return;
  59.         }
  60.         if ($eventType->isGroupMeetingType() && $event->getLocation()) {
  61.             return;
  62.         }
  63.         if ($event->isRecurring() && $event->getLocation()) {
  64.             return;
  65.         }
  66.         try {
  67.             $zoomClientAdapter $this->zoomClientProvider->getZoomClient($integration);
  68.             $zoomMeeting $zoomClientAdapter->createMeeting($event);
  69.         } catch (\Exception $e) {
  70.             $this->logger->critical($e->getMessage());
  71.             return;
  72.         }
  73.         $event->setLocation($zoomMeeting['join_url']);
  74.     }
  75.     public function cancelMeeting(GenericEvent $genericEvent): void
  76.     {
  77.         /** @var EventInterface $event */
  78.         $event $genericEvent->getSubject();
  79.         Assert::isInstanceOf($eventEventInterface::class);
  80.         $eventType $event->getEventType();
  81.         $user $genericEvent->hasArgument('previousUser')
  82.             ? $genericEvent->getArgument('previousUser')
  83.             : $event->getUser();
  84.         $locationType $this->locationTypeProvider->provideFor($eventType$user$event);
  85.         $integration $this->findIntegration($user);
  86.         if (null === $integration || EventTypeInterface::LOCATION_TYPE_ZOOM !== $locationType) {
  87.             return;
  88.         }
  89.         if (!$integration->isEnabled()) {
  90.             return;
  91.         }
  92.         if ($eventType->isGroupMeetingType() && $event->getLocation()) {
  93.             return;
  94.         }
  95.         if ($event->isRecurring() && $event->getLocation()) {
  96.             return;
  97.         }
  98.         try {
  99.             $zoomClientAdapter $this->zoomClientProvider->getZoomClient($integration);
  100.             $zoomClientAdapter->cancelMeeting($event);
  101.         } catch (\Exception $e) {
  102.             $this->logger->critical('Zoom meeting cancellation failed.', [
  103.                 'message' => $e->getMessage(),
  104.                 'user_email' => $user->getEmail(),
  105.                 'invitee_email' => $event->getInvitee()->getEmail(),
  106.             ]);
  107.         }
  108.     }
  109.     public function updateMeeting(GenericEvent $genericEvent): void
  110.     {
  111.         /** @var EventInterface $event */
  112.         $event $genericEvent->getSubject();
  113.         Assert::isInstanceOf($eventEventInterface::class);
  114.         /** @var EventTypeInterface $eventType */
  115.         $eventType $event->getEventType();
  116.         $user $event->getUser();
  117.         if ($event->isRecurring() && $event->getLocation()) {
  118.             return;
  119.         }
  120.         if ($event->getRescheduling()->getPreviousUser()) {
  121.             $genericEvent->setArgument('previousUser'$event->getRescheduling()->getPreviousUser());
  122.             $this->cancelMeeting($genericEvent);
  123.             $this->createMeeting($genericEvent);
  124.         } else {
  125.             $locationType $this->locationTypeProvider->provideFor($eventType$user$event);
  126.             $integration $this->findIntegration($user);
  127.             if (null === $integration || EventTypeInterface::LOCATION_TYPE_ZOOM !== $locationType) {
  128.                 return;
  129.             }
  130.             if (!$integration->isEnabled()) {
  131.                 return;
  132.             }
  133.             $eventType $event->getEventType();
  134.             $startTimeInUserTimezone = clone $event->getScheduledAt();
  135.             $startTimeInUserTimezone->setTimezone(new DateTimeZone($eventType->getUser()->getTimezone()));
  136.             $startsAt $startTimeInUserTimezone->format('Y-m-d\\TH:i:s');
  137.             $invitee $event->getInvitee();
  138.             $topic $event->getVisibleEventName().' - '.$invitee->getFullName();
  139.             $duration $event->getDuration();
  140.             if (null === ($zoomLink $event->getLocation())) {
  141.                 return;
  142.             }
  143.             $zoomMeetingId = (int) basename($zoomLink);
  144.             try {
  145.                 $zoomClientAdapter $this->zoomClientProvider->getZoomClient($integration);
  146.                 $zoomClientAdapter->updateMeeting($zoomMeetingId$topic$duration$startsAt);
  147.             } catch (CouldNotUpdateZoomMeetingException $e) {
  148.                 $this->logger->critical($e->getMessage());
  149.                 return;
  150.             }
  151.         }
  152.     }
  153.     private function findIntegration(UserInterface $user): ?IntegrationInterface
  154.     {
  155.         $integrationRepository $this->entityManager->getRepository(Integration::class);
  156.         return $integrationRepository->findOneBy([
  157.             'type' => IntegrationType::TYPE_ZOOM,
  158.             'user' => $user,
  159.         ]);
  160.     }
  161. }