entityManager = $entityManager; $this->clientManager = $clientManager; $this->hookManager = $hookManager; $this->config = $config; $this->metadata = $metadata; $this->hasher = $hasher; $this->util = $util; } public function run(Request $request, Response $response): void { $id = $request->getQueryParam('id') ?? null; $emailAddress = $request->getQueryParam('emailAddress') ?? null; $hash = $request->getQueryParam('hash') ?? null; if ($emailAddress && $hash) { $this->processWithHash($emailAddress, $hash); return; } if (!$id || !is_string($id)) { throw new BadRequest(); } $queueItemId = $id; $queueItem = $this->entityManager->getEntity('EmailQueueItem', $queueItemId); if (!$queueItem) { throw new NotFound(); } $campaign = null; $target = null; $campaignId = null; $massEmailId = $queueItem->get('massEmailId'); if ($massEmailId) { $massEmail = $this->entityManager->getEntity('MassEmail', $massEmailId); if ($massEmail) { $campaignId = $massEmail->get('campaignId'); if ($campaignId) { $campaign = $this->entityManager->getEntity('Campaign', $campaignId); } $targetType = $queueItem->get('targetType'); $targetId = $queueItem->get('targetId'); if ($targetType && $targetId) { $target = $this->entityManager->getEntity($targetType, $targetId); if (!$target) { throw new NotFound(); } if ($massEmail->get('optOutEntirely')) { $emailAddress = $target->get('emailAddress'); if ($emailAddress) { $ea = $this->getEmailAddressRepository()->getByAddress($emailAddress); if ($ea) { $ea->set('optOut', false); $this->entityManager->saveEntity($ea); } } } $link = $this->util->getLinkByEntityType($target->getEntityType()); $targetListList = $this->entityManager ->getRDBRepository('MassEmail') ->getRelation($massEmail, 'targetLists') ->find(); foreach ($targetListList as $targetList) { $optedInResult = $this->entityManager ->getRDBRepository('TargetList') ->updateRelation($targetList, $link, $target->getId(), ['optedOut' => false]); if ($optedInResult) { $hookData = [ 'link' => $link, 'targetId' => $targetId, 'targetType' => $targetType, ]; $this->hookManager ->process('TargetList', 'afterCancelOptOut', $targetList, [], $hookData); } } $this->hookManager->process($target->getEntityType(), 'afterCancelOptOut', $target, [], []); $this->display(['queueItemId' => $queueItemId]); } } } if ($campaign && $target) { $logRecord = $this->entityManager ->getRDBRepository('CampaignLogRecord')->where([ 'queueItemId' => $queueItemId, 'action' => 'Opted Out', ]) ->order('createdAt', true) ->findOne(); if ($logRecord) { $this->entityManager->removeEntity($logRecord); } } } /** * @param array $actionData */ protected function display(array $actionData): void { $data = [ 'actionData' => $actionData, 'view' => $this->metadata->get(['clientDefs', 'Campaign', 'subscribeView']), 'template' => $this->metadata->get(['clientDefs', 'Campaign', 'subscribeTemplate']), ]; $runScript = " Espo.require('crm:controllers/unsubscribe', function (Controller) { var controller = new Controller(app.baseController.params, app.getControllerInjection()); controller.masterView = app.masterView; controller.doAction('subscribeAgain', ".json_encode($data)."); }); "; $this->clientManager->display($runScript); } protected function processWithHash(string $emailAddress, string $hash): void { $hash2 = $this->hasher->hash($emailAddress); if ($hash2 !== $hash) { throw new NotFound(); } $repository = $this->getEmailAddressRepository(); $ea = $repository->getByAddress($emailAddress); if ($ea) { $entityList = $repository->getEntityListByAddressId($ea->getId()); if ($ea->get('optOut')) { $ea->set('optOut', false); $this->entityManager->saveEntity($ea); foreach ($entityList as $entity) { $this->hookManager->process($entity->getEntityType(), 'afterCancelOptOut', $entity, [], []); } } $this->display([ 'emailAddress' => $emailAddress, 'hash' => $hash, ]); } else { throw new NotFound(); } } private function getEmailAddressRepository(): EmailAddressRepository { /** @var EmailAddressRepository */ return $this->entityManager->getRepository('EmailAddress'); } }