<?php
namespace App\EventSubscriber\Doctrine;
use App\Enum\LetterStatusEnum;
use App\Message\OCRIndexationMessage;
use App\Service\LetterFilesService;
use App\Service\SegmentAPI;
use App\Traits\SentryNotifyTrait;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Evo\Infrastructure\MappingORM\Letter;
use Evo\Infrastructure\MappingORM\Organization;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class LetterSubscriber implements EventSubscriber
{
use SentryNotifyTrait;
private LetterFilesService $letterFilesService;
private SegmentAPI $segmentAPI;
private HttpClientInterface $client;
private EntityManagerInterface $em;
private MessageBusInterface $bus;
public function __construct(
LetterFilesService $letterFilesService,
SegmentAPI $segmentAPI,
HttpClientInterface $client,
EntityManagerInterface $em,
MessageBusInterface $bus
) {
$this->letterFilesService = $letterFilesService;
$this->segmentAPI = $segmentAPI;
$this->client = $client;
$this->em = $em;
$this->bus = $bus;
}
/**
* Returns an array of events this subscriber wants to listen to.
*
* @return string[]
*/
public function getSubscribedEvents()
{
return [
'postPersist',
'postUpdate',
'preRemove',
];
}
public function postPersist(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if (!$entity instanceof Letter) {
return;
}
$this->sendLetterToAws($entity, $args);
if (LetterStatusEnum::TO_BE_SENT === $entity->getStatus()) {
$organization = $entity->getOrganization();
if (null !== $organization) {
$organization->setIsEmptybal(false);
$args->getObjectManager()->persist($organization);
$args->getObjectManager()->flush();
}
}
$organization = $entity->getOrganization();
if ($organization && !empty($organization->getZapierHookUrl())) {
$params = [
'type' => $entity->getType(),
'organization' => $organization,
'letterId' => $entity->getId(),
];
foreach ($organization->getZapierHookUrl() as $zapierHookUrl) {
if (isset($zapierHookUrl['letter']) && 'letter' === array_keys($zapierHookUrl)[0]) {
$response = $this->client->request(
'POST',
$zapierHookUrl['letter'],
[
'body' => $params,
]
);
if (410 === $response->getStatusCode()) {
$this->sendSentryMessage('[ZAPIER] Unsubscribe Zap 410 returned');
continue;
}
} elseif (isset($zapierHookUrl['letter_with_ar']) && 'letter_with_ar' === array_keys($zapierHookUrl)[0]) {
$response = $this->client->request(
'POST',
$zapierHookUrl['letter_with_ar'],
[
'body' => $params,
]
);
if (410 === $response->getStatusCode()) {
$this->sendSentryMessage('[ZAPIER] Unsubscribe Zap 410 returned');
continue;
}
} elseif (isset($zapierHookUrl['parcel']) && 'parcel' === array_keys($zapierHookUrl)[0]) {
$response = $this->client->request(
'POST',
$zapierHookUrl['parcel'],
[
'body' => $params,
]
);
if (410 === $response->getStatusCode()) {
$this->sendSentryMessage('[ZAPIER] Unsubscribe Zap 410 returned');
continue;
}
} elseif (isset($zapierHookUrl['bailiff_notice']) && 'bailiff_notice' === array_keys($zapierHookUrl)[0]) {
$response = $this->client->request(
'POST',
$zapierHookUrl['bailiff_notice'],
[
'body' => $params,
]
);
if (410 === $response->getStatusCode()) {
$this->sendSentryMessage('[ZAPIER] Unsubscribe Zap 410 returned');
continue;
}
}
}
}
$this->segmentAPI->trackNewLetter($entity);
if (null !== $entity->getContentPathAWS()) {
$this->bus->dispatch(OCRIndexationMessage::createWithLetterId($entity->getId()));
}
}
public function postUpdate(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if (!$entity instanceof Letter) {
return;
}
$this->sendLetterToAws($entity, $args);
$uow = $this->em->getUnitOfWork();
$uow->computeChangeSets();
$changeset = $uow->getEntityChangeSet($entity);
if (isset($changeset['status']) && LetterStatusEnum::DESTROYED === $changeset['status'][1]) {
$this->segmentAPI->trackDestroyedLetter($entity);
}
if (LetterStatusEnum::TO_BE_SENT === $entity->getStatus()) {
$entity->getOrganization()->setIsEmptybal(false);
$args->getObjectManager()->persist($args->getObjectManager()->getRepository(Organization::class)->find($entity->getOrganization()->getId()));
$args->getObjectManager()->flush();
}
if (null !== $entity->getContentPathAWS() && $organization = $entity->getOrganization()) {
$this->bus->dispatch(OCRIndexationMessage::createWithOrganizationIdAndLetterId($organization->getId(), $entity->getId()));
}
}
private function sendLetterToAws(Letter $entity, $args)
{
$response = $this->letterFilesService->sendToAWS($entity);
if (!empty($response)) {
if (isset($response['front'])) {
$entity->setEnvelopeFrontPath(null);
$entity->setEnvelopeFrontPathAWS($response['front']);
}
if (isset($response['back'])) {
$entity->setEnvelopeBackPath(null);
$entity->setEnvelopeBackPathAWS($response['back']);
}
if (isset($response['content'])) {
$entity->setContentPath(null);
$entity->setContentPathAWS($response['content']);
}
$args->getObjectManager()->persist($entity);
$args->getObjectManager()->flush();
}
}
public function preRemove(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if (!$entity instanceof Letter) {
return;
}
$this->segmentAPI->trackDeletedLetter($entity);
}
}