<?php
declare(strict_types=1);
namespace App\Component\ExternalIntegration\EventSubscriber;
use App\Component\ExternalIntegration\AbstractExternalIntegration;
use App\Component\ExternalIntegration\DependencyInjection\ExternalIntegrationCollection;
use App\Component\ExternalIntegration\Event\PostApplicantFailEvent;
use App\Component\ExternalIntegration\Event\PostApplicantSuccessEvent;
use App\Component\ExternalIntegration\Message\Command\SendApplication;
use App\Component\GDPR\Anonymize\AnonymizeApplicant;
use App\Enum\DataTypeEnum;
use App\Event\ApplicantEvent;
use App\Mail\NotificationAddress;
use App\Mail\RecipientsByImportance;
use App\Notification\ExternalApplicantNotification;
use App\Util\TypeUtil;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Notifier\NotifierInterface;
class SendApplicationSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly ExternalIntegrationCollection $externalIntegrationCollection,
private readonly MessageBusInterface $messageBus,
private readonly AnonymizeApplicant $anonymizeApplicant,
private readonly NotifierInterface $notifier,
private readonly RecipientsByImportance $recipientsByImportance,
private readonly NotificationAddress $notificationAddress,
) {
}
public static function getSubscribedEvents(): array
{
return [
ApplicantEvent::EVENT_POST_PERSIST => 'onApplicantPostPersist',
PostApplicantSuccessEvent::class => 'onPostApplicantSuccess',
PostApplicantFailEvent::class => 'onPostApplicantFail',
];
}
public function onApplicantPostPersist(ApplicantEvent $applicantEvent): void
{
$applicant = $applicantEvent->getApplicant();
$externalReference = $applicant->getExternalVacancyReference() ?? '';
if (!TypeUtil::checkTypeAndTruthy($externalReference, DataTypeEnum::STRING)
&& $this->externalIntegrationCollection->hasActiveExternalIntegrations()
) {
$activeExternalIntegrations = $this->externalIntegrationCollection->getActiveExternalIntegrations();
/** @var AbstractExternalIntegration $firstActiveIntegration */
$firstActiveIntegration = reset($activeExternalIntegrations);
$externalReference = $firstActiveIntegration::getReference();
}
// only accept vacancies with valid external reference
if (!TypeUtil::checkTypeAndTruthy($externalReference, DataTypeEnum::STRING)
|| !\is_int($applicant->getId())
) {
return;
}
$this->messageBus->dispatch(new SendApplication($applicant->getId(), $externalReference));
}
public function onPostApplicantSuccess(PostApplicantSuccessEvent $event): void
{
$from = $this->notificationAddress->getFrom();
$applicant = $event->getApplicant();
if (\is_string($applicant->getExternalId())
&& \is_string($applicant->getExternalCandidateId())
) {
$this->anonymizeApplicant->anonymize($applicant);
} elseif ('' !== $from) {
$notification = ExternalApplicantNotification::create(
$from,
$event->getAts(),
$applicant,
'An Applicant could not be anonymized.'
);
$this->notifier->send(
$notification,
...$this->recipientsByImportance->get($notification->getImportance())
);
}
}
public function onPostApplicantFail(PostApplicantFailEvent $event): void
{
$from = $this->notificationAddress->getFrom();
if ('' !== $from) {
$notification = ExternalApplicantNotification::create(
$from,
$event->getAts(),
$event->getApplicant(),
'Applicant could not be sent.'
.\PHP_EOL
.($event->getThrowable()?->getMessage() ?? 'There was no error message.')
);
$this->notifier->send($notification, ...$this->recipientsByImportance->get($notification->getImportance()));
}
}
}