recordServiceContainer = $recordServiceContainer; $this->sendService = $sendService; $this->user = $user; $this->injectableFactory = $injectableFactory; $this->acl = $acl; $this->entityManager = $entityManager; $this->config = $config; } /** * Send invitation emails for a meeting (or call). Checks access. Uses user's SMTP if available. * * @param ?Invitee[] $targets * @return Entity[] Entities an invitation was sent to. * @throws NotFound * @throws Forbidden * @throws Error * @throws SendingError */ public function send(string $entityType, string $id, ?array $targets = null): array { return $this->sendInternal($entityType, $id, $targets); } /** * Send cancellation emails for a meeting (or call). Checks access. Uses user's SMTP if available. * * @param ?Invitee[] $targets * @return Entity[] Entities a cancellation was sent to. * @throws NotFound * @throws Forbidden * @throws Error * @throws SendingError */ public function sendCancellation(string $entityType, string $id, ?array $targets = null): array { return $this->sendInternal($entityType, $id, $targets, self::TYPE_CANCELLATION); } /** * @param ?Invitee[] $targets * @return Entity[] * @throws NotFound * @throws Forbidden * @throws Error * @throws SendingError */ private function sendInternal( string $entityType, string $id, ?array $targets = null, string $type = self::TYPE_INVITATION ): array { $entity = $this->recordServiceContainer ->get($entityType) ->getEntity($id); if (!$entity) { throw new NotFound(); } if (!$this->acl->checkEntityEdit($entity)) { throw new Forbidden("No edit access."); } $linkList = [ 'users', 'contacts', 'leads', ]; $sender = $this->getSender(); $sentAddressList = []; $resultEntityList = []; foreach ($linkList as $link) { $builder = $this->entityManager ->getRDBRepository($entityType) ->getRelation($entity, $link); if ($targets === null && $type === self::TYPE_INVITATION) { $builder->where([ '@relation.status=' => Meeting::ATTENDEE_STATUS_NONE, ]); } $collection = $builder->find(); foreach ($collection as $attendee) { if ($targets && !self::isInTargets($attendee, $targets)) { continue; } $emailAddress = $attendee->get('emailAddress'); if (!$emailAddress || in_array($emailAddress, $sentAddressList)) { continue; } if ($type === self::TYPE_INVITATION) { $sender->sendInvitation($entity, $attendee, $link); } if ($type === self::TYPE_CANCELLATION) { $sender->sendCancellation($entity, $attendee, $link); } $sentAddressList[] = $emailAddress; $resultEntityList[] = $attendee; $this->entityManager ->getRDBRepository($entityType) ->getRelation($entity, $link) ->updateColumns($attendee, ['status' => Meeting::ATTENDEE_STATUS_NONE]); } } return $resultEntityList; } /** * @param Invitee[] $targets */ private static function isInTargets(Entity $entity, array $targets): bool { foreach ($targets as $target) { if ( $entity->getEntityType() === $target->getEntityType() && $entity->getId() === $target->getId() ) { return true; } } return false; } private function getSender(): Invitations { $smtpParams = !$this->config->get('eventInvitationForceSystemSmtp') ? $this->sendService->getUserSmtpParams($this->user->getId()) : null; $builder = BindingContainerBuilder::create(); if ($smtpParams) { $builder->bindInstance(SmtpParams::class, $smtpParams); } return $this->injectableFactory->createWithBinding(Invitations::class, $builder->build()); } }