getQueryParam('id') ?? null; $emailAddress = $request->getQueryParam('emailAddress') ?? null; $hash = $request->getQueryParam('hash') ?? null; if ($emailAddress && $hash) { $this->processWithHash($response, $emailAddress, $hash); return; } if (!$id || !is_string($id)) { throw new BadRequest(); } $queueItemId = $id; /** @var ?EmailQueueItem $queueItem */ $queueItem = $this->entityManager->getEntity(EmailQueueItem::ENTITY_TYPE, $queueItemId); if (!$queueItem) { throw new NotFound(); } $campaign = null; $target = null; $massEmail = null; $massEmailId = $queueItem->getMassEmailId(); if ($massEmailId) { /** @var ?MassEmail $massEmail */ $massEmail = $this->entityManager->getEntity(MassEmail::ENTITY_TYPE, $massEmailId); } if ($massEmail) { $campaignId = $massEmail->getCampaignId(); if ($campaignId) { $campaign = $this->entityManager->getEntityById(Campaign::ENTITY_TYPE, $campaignId); } $targetType = $queueItem->getTargetType(); $targetId = $queueItem->getTargetId(); $target = $this->entityManager->getEntityById($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()); /** @var Collection $targetListList */ $targetListList = $this->entityManager ->getRDBRepository(MassEmail::ENTITY_TYPE) ->getRelation($massEmail, 'targetLists') ->find(); foreach ($targetListList as $targetList) { $relation = $this->entityManager ->getRDBRepository(TargetList::ENTITY_TYPE) ->getRelation($targetList, $link); if (!$relation->getColumn($target, 'optedOut')) { continue; } $relation->updateColumnsById($target->getId(), ['optedOut' => false]); $hookData = [ 'link' => $link, 'targetId' => $targetId, 'targetType' => $targetType, ]; $this->hookManager ->process(TargetList::ENTITY_TYPE, 'afterCancelOptOut', $targetList, [], $hookData); } $this->hookManager->process($target->getEntityType(), 'afterCancelOptOut', $target, [], []); $this->display($response, ['queueItemId' => $queueItemId]); } if ($campaign && $target) { $logRecord = $this->entityManager ->getRDBRepository(CampaignLogRecord::ENTITY_TYPE) ->where([ 'queueItemId' => $queueItemId, 'action' => CampaignLogRecord::ACTION_OPTED_OUT, ]) ->order('createdAt', true) ->findOne(); if ($logRecord) { $this->entityManager->removeEntity($logRecord); } } } /** * @param array $actionData */ protected function display(Response $response, array $actionData): void { $data = [ 'actionData' => $actionData, 'view' => $this->metadata->get(['clientDefs', 'Campaign', 'subscribeView']), 'template' => $this->metadata->get(['clientDefs', 'Campaign', 'subscribeTemplate']), ]; $params = ActionRenderer\Params::create('crm:controllers/unsubscribe', 'subscribeAgain', $data); $this->actionRenderer->write($response, $params); } /** * @throws NotFound */ protected function processWithHash(Response $response, 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) { throw new NotFound(); } $entityList = $repository->getEntityListByAddressId($ea->getId()); if ($ea->isOptedOut()) { $ea->set('optOut', false); $this->entityManager->saveEntity($ea); foreach ($entityList as $entity) { $this->hookManager->process($entity->getEntityType(), 'afterCancelOptOut', $entity, [], []); } } $this->display($response, [ 'emailAddress' => $emailAddress, 'hash' => $hash, ]); } private function getEmailAddressRepository(): EmailAddressRepository { /** @var EmailAddressRepository */ return $this->entityManager->getRepository('EmailAddress'); } }