<?php
namespace App\EventListener;
use App\Component\Configuration\Util\Config;
use App\Entity\Applicant;
use App\Entity\Company;
use App\Entity\Mail;
use App\Entity\Vacancy;
use App\Entity\VacancyDomain;
use App\Event\ApplicantEvent;
use App\Form\Setting\ApplicantSettingType as ApplicantSettings;
use App\Sendgrid\MailerInterface;
use App\Service\SiteService;
use App\Util\StringToEntityUtil;
use Doctrine\ORM\EntityManagerInterface;
use Flagception\Manager\FeatureManagerInterface;
use Gedmo\Translatable\TranslatableListener;
use League\Flysystem\Adapter\Local;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Routing\RouterInterface;
class ApplicantApplicantEventListener extends FormSubmitEventListener
{
private EntityManagerInterface $entityManager;
private FeatureManagerInterface $featureManager;
private Local $fileAdapter;
private SiteService $siteService;
private RouterInterface $router;
private EntityManagerInterface $parentEntityManager;
/**
* ApplicantApplicantEventListener constructor.
*/
public function __construct(
EntityManagerInterface $entityManager,
FeatureManagerInterface $featureManager,
ParameterBagInterface $parameterBag,
MailerInterface $mailer,
StringToEntityUtil $stringToEntityUtil,
Local $fileAdapter,
SiteService $siteService,
RouterInterface $router,
?TranslatableListener $translatableListener,
EntityManagerInterface $parentEntityManager,
Config $config
) {
$this->entityManager = $entityManager;
$this->featureManager = $featureManager;
$this->fileAdapter = $fileAdapter;
$this->siteService = $siteService;
$this->router = $router;
$this->config = $config;
parent::__construct($mailer, $parameterBag, $stringToEntityUtil, $translatableListener, $config);
$this->parentEntityManager = $parentEntityManager;
}
public function applicantSubmitted(ApplicantEvent $applicantEvent)
{
if (
$this->featureManager->isActive('feature_ats') ||
$this->featureManager->isActive(FeatureFlagListener::FEATURE_PEOPLE_XS_SEND_APPLICANT)
) {
return;
}
$applicant = $applicantEvent->getApplicant();
$vacancyUrl = '';
$vacancyDomain = null;
if ($applicant->getVacancy()) {
$vacancyUrl = $this->router->generate('vacancy_detail', ['id' => $applicant->getVacancy()->getId(), 'slug' => $applicant->getVacancy()->getSlug()]);
$vacancyDomain = $applicant->getVacancy()->getDomain();
}
$sender = null;
if ($vacancyDomain && $vacancyDomain->getMailSet()) {
$sender = [$vacancyDomain->getMailSet()->getSenderEmail() => $vacancyDomain->getMailSet()->getSenderName()];
}
[$visitorMail, $ownerMail] = $this->getMailTemplates($applicant, $vacancyDomain);
if ($visitorMail && $this->config->get('site_applicant_applicant_send_mail')) {
$this->sendApplicantMail($applicant, $visitorMail, $applicantEvent, $vacancyUrl, $sender);
}
if ($ownerMail && $this->config->get('site_applicant_company_send_mail')) {
$this->sendCompanyMail($applicant, $ownerMail, $applicantEvent, $vacancyUrl, $sender);
}
if (!$this->featureManager->isActive(FeatureFlagListener::FEATURE_CREDITS)
|| !$this->featureManager->isActive(FeatureFlagListener::FEATURE_APPLICANT_DONT_SAVE_TO_DB)) {
$this->updateApplicantSendToApplicationMail($applicant);
}
}
private function updateApplicantSendToApplicationMail(Applicant $applicant)
{
$entityManager = $this->entityManager;
if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_CHILD_SITE)) {
$entityManager = $this->parentEntityManager;
}
$applicant->setApplicantSendToApplicantMail(true);
$entityManager->persist($applicant);
$entityManager->flush();
}
private function sendApplicantMail(
Applicant $applicant,
Mail $applicantMail,
ApplicantEvent $applicantEvent,
string $vacancyUrl,
?array $sender = null
) {
if (!$applicantEvent->isResend() &&
$applicant->getEmail()
) {
$this->mailer->mail(
$applicantMail,
$sender ?: $this->getCompanyEmailSender(),
[$applicant->getEmail()],
['applicant' => $applicant, 'site' => $this->siteService->getSite(), 'vacancyUrl' => $vacancyUrl]
);
}
}
private function sendCompanyMail(
Applicant $applicant,
Mail $companyMail,
ApplicantEvent $applicantEvent,
string $vacancyUrl,
?array $sender = null
) {
if ($applicant->getVacancy()) {
$recipientEmailAddress = $this->getVacancyApplicationCompanyEmail($applicant->getVacancy());
} else {
$recipientEmailAddress = $this->getOpenApplicationCompanyEmail($applicantEvent);
}
$files = [];
if ($this->config->get('site_applicant_attach_files')) {
if ($applicant->getFileName() && $this->fileAdapter->has($applicant->getFileName())) {
$files[] = $this->fileAdapter->getPathPrefix().$applicant->getFileName();
}
if ($applicant->getFileNameMotivation() && $this->fileAdapter->has($applicant->getFileNameMotivation())) {
$files[] = $this->fileAdapter->getPathPrefix().$applicant->getFileNameMotivation();
}
}
$this->mailer->mail(
$companyMail,
$sender ?: $this->getCompanyEmailSender(),
\is_string($recipientEmailAddress) ? [$recipientEmailAddress] : $recipientEmailAddress,
[
'applicant' => $applicant,
'site' => $this->siteService->getSite(),
'vacancyUrl' => $vacancyUrl,
'utm_source' => $applicant->getUtm()['utm_source'] ?? null,
'utm_medium' => $applicant->getUtm()['utm_medium'] ?? null,
'utm_campaign' => $applicant->getUtm()['utm_campaign'] ?? null,
'utm_term' => $applicant->getUtm()['utm_term'] ?? null,
'utm_content' => $applicant->getUtm()['utm_content'] ?? null,
],
[],
[],
$files
);
}
private function getVacancyApplicationCompanyEmail(Vacancy $vacancy): string|array
{
$emailPolicy = $this->config->get('site_applicant_applications_email_policy_company');
// Always 'prefer' applicantEmail when available
if (!empty($vacancy->getApplicantEmail())) {
return $vacancy->getApplicantEmail();
}
if (
ApplicantSettings::APPLICATION_NOTIFICATION_POLICY_VACANCY_RELATED_COMPANY === $emailPolicy &&
$company = $vacancy->getCompany()
) {
if (!empty($company->getApplicantEmail())) {
return $company->getApplicantEmail();
}
if (!empty($company->getEmail())) {
return $company->getEmail();
}
}
if (
ApplicantSettings::APPLICATION_NOTIFICATION_POLICY_VACANCY_RELATED_RECRUITER === $emailPolicy &&
$vacancy->getRecruiter() &&
$relatedRecruiterEmailAddress = $vacancy->getRecruiter()->getEmail()
) {
return $relatedRecruiterEmailAddress;
}
$address = $this->parameterBag->get('site_company_email_address');
return \is_string($address) ? $address : [];
}
private function getOpenApplicationCompanyEmail(ApplicantEvent $applicantEvent): string|array
{
$emailPolicy = $this->config->get('site_applicant_open_applications_email_policy_company');
if (ApplicantSettings::OPEN_APPLICATION_NOTIFICATION_POLICY_GLOBAL === $emailPolicy) {
$address = $this->parameterBag->get('site_company_email_address');
return \is_string($address) ? $address : [];
}
if (
ApplicantSettings::OPEN_APPLICATION_NOTIFICATION_POLICY_CUSTOM === $emailPolicy &&
$customAddress = $this->config->get('site_applicant_open_applications_company_custom_email')
) {
return \is_string($customAddress) ? $customAddress : [];
}
if (
ApplicantSettings::OPEN_APPLICATION_NOTIFICATION_POLICY_COMPANY === $emailPolicy &&
$applicantEvent->getForm()?->has('company') &&
Company::class === \get_class($applicantEvent->getForm()?->get('company')->getData())
) {
/** @var Company $company */
$company = $applicantEvent->getForm()?->get('company')->getData();
if (!empty($company->getApplicantEmail())) {
return $company->getApplicantEmail();
}
if (!empty($company->getEmail())) {
return $company->getEmail();
}
}
$address = $this->parameterBag->get('site_company_email_address');
return \is_string($address) ? $address : [];
}
private function getMailTemplates(Applicant $applicant, ?VacancyDomain $vacancyDomain): array
{
if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_VACANCY_KNOCKOUT_QUESTIONS)
&& $applicant->isRejectedByKnockout()
) {
$visitorRejectMail = $this->getMail('site_applicant_applicant_reject_mail');
$ownerRejectMail = $this->getMail('site_applicant_company_reject_email');
return [$visitorRejectMail, $ownerRejectMail];
}
if (!$applicant->getVacancy()) {
$visitorOpenMail = $this->getMail('site_applicant_open_applicant_mail');
$ownerOpenRejectMail = $this->getMail('site_applicant_open_company_email');
return [$visitorOpenMail, $ownerOpenRejectMail];
}
if ($vacancyDomain && $vacancyDomain->getMailSet()) {
return [
$vacancyDomain->getMailSet()->getVisitorMailTemplate(),
$vacancyDomain->getMailSet()->getOwnerMailTemplate(),
];
}
$visitorMail = $this->getMail('site_applicant_applicant_mail');
$ownerMail = $this->getMail('site_applicant_company_email');
return [$visitorMail, $ownerMail];
}
}