<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Application;
use App\Entity\BaseUser;
use App\Entity\Pharmacy;
use App\Event\Application\ApplicationMailRequest;
use App\Event\JobPosting\ApplicationRefused;
use App\Kernel;
use App\Repository\ApplicationRepository;
use App\Repository\BaseUserRepository;
use App\Services\BaseUserService;
use ExpoSDK\Expo;
use ExpoSDK\ExpoMessage;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mailer\MailerInterface;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
final class ApplicationSubscriber implements EventSubscriberInterface
{
private MailerInterface $mailer;
private UploaderHelper $helper;
private Kernel $kernel;
private BaseUserRepository $baseUserRepository;
private BaseUserService $baseUserService;
private ApplicationRepository $applicationRepository;
public function __construct(MailerInterface $mailer, UploaderHelper $helper, Kernel $kernel, BaseUserRepository $baseUserRepository, BaseUserService $baseUserService, ApplicationRepository $applicationRepository)
{
$this->mailer = $mailer;
$this->helper = $helper;
$this->kernel = $kernel;
$this->baseUserRepository = $baseUserRepository;
$this->baseUserService = $baseUserService;
$this->applicationRepository = $applicationRepository;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['create', EventPriorities::POST_WRITE],
ApplicationMailRequest::class => ['sendMailInformation'],
ApplicationRefused::class => ['applicationRefused']
];
}
public function create(ViewEvent $event): void
{
$application = $event->getControllerResult();
$request = $event->getRequest();
$method = $request->getMethod();
if (
!$application instanceof Application
|| Request::METHOD_POST !== $method
|| $request->get('_route') !== 'api_applications_post_collection'
) {
return;
}
if ($devices = $this->baseUserService->getDevicesTokenFromRole('ROLE_ADMIN')) {
$this->sendPushCreate($devices);
}
/**
* MAIL:User
*/
$email = (new TemplatedEmail())
->from(new Address('noreply@ores.com', 'ORES'))
->to($application->getUser()->getEmail())
->subject('Merci pour votre candidature - ORES BFC')
->htmlTemplate('mails/application/create.html.twig')
->context([
'application' => $application
]);
$this->mailer->send($email);
/**
* Information d'une candidature pour le propriétaire d'officine
*/
$pharmacy = $application->getJobPosting()->getPharmacy();
$devices = $pharmacy->getDevicesTokensExpo();
switch ($pharmacy->getNotificationType()) {
case BaseUser::NOTIFICATION_MAIL:
$this->sendMailCreatePharmacy($pharmacy, $application);
break;
case BaseUser::NOTIFICATION_PUSH:
if ($devices) $this->sendPushCreate($devices);
break;
case BaseUser::NOTIFICATION_PUSH_MAIL:
$this->sendMailCreatePharmacy($pharmacy, $application);
if ($devices) $this->sendPushCreate($devices);
break;
}
}
public function sendMailCreatePharmacy(Pharmacy $pharmacy, Application $application)
{
/**
* MAIL:Pharmacy
*/
$email = (new TemplatedEmail())
->from(new Address('noreply@ores.com', 'ORES'))
->to($pharmacy->getEmail())
->subject('Nouvelle candidature sur votre offre - ORES BFC')
->htmlTemplate('mails/application/create_pharmacy.html.twig')
->context([
'pharmacy' => $pharmacy,
'application' => $application
])
->attachFromPath($this->kernel->getProjectDir().'/public'.$this->helper->asset($application, "cvUploaded"));
if ($application->getMotivationLetter()) {
$email->attachFromPath($this->kernel->getProjectDir().'/public'.$this->helper->asset($application, "motivationLetterUploaded"));
}
$this->mailer->send($email);
}
public function sendMailInformation(ApplicationMailRequest $request)
{
$baseUser = $request->getUser();
$application = $request->getApplication();
$userFromDB = $application->getUser();
$user = [
'lastname' => $userFromDB->getLastname(),
'firstname' => $userFromDB->getFirstname(),
'phone' => $userFromDB->getPhone(),
'email' => $userFromDB->getEmail(),
];
/**
* MAIL:Pharmacy
*/
$email = (new TemplatedEmail())
->from(new Address('noreply@ores.com', 'ORES'))
->to($baseUser->getEmail())
->subject('Informations sur une candidature - ORES BFC')
->htmlTemplate('mails/application/information_request.html.twig')
->context([
'baseUser' => $baseUser,
'application' => $application,
'user' => $user,
])
->attachFromPath($this->kernel->getProjectDir().'/public'.$this->helper->asset($application, "cvUploaded"));
if ($application->getMotivationLetter()) {
$email->attachFromPath($this->kernel->getProjectDir().'/public'.$this->helper->asset($application, "motivationLetterUploaded"));
}
$this->mailer->send($email);
}
public function sendPushCreate(?array $devices)
{
/**
* PUSH:Pharmacy PUSH:Admin
*/
$message = (new ExpoMessage([
'title' => 'Nouvelle candidature',
'body' => 'Une nouvelle demande de candidature.',
]))
->setChannelId('default')
->setBadge(0)
->playSound();
if (!empty($devices)) {
return (new Expo)->send($message)->to($devices)->push();
}
}
public function sendMailApplicationRefused(Application $application)
{
/**
* MAIL:User
*/
$email = (new TemplatedEmail())
->from(new Address('noreply@ores.com', 'ORES'))
->to($application->getUser()->getEmail())
->subject('Candidature refusée - ORES BFC')
->htmlTemplate('mails/application/refused.html.twig')
->context([
'application' => $application
]);
$this->mailer->send($email);
return $application;
}
public function sendPushApplicationRefused(?array $to, Application $application)
{
/**
* PUSH:BaseUser
*/
$message = (new ExpoMessage([
'title' => 'Candidature refusé',
'body' => "Votre demande de candidature pour l’offre “".$application->getJobPosting()->getTitle()."” pour l’officine “".$application->getJobPosting()->getPharmacy()->getLegalname()."” a été refusée.",
]))
->setChannelId('default')
->setBadge(0)
->playSound();
if (!empty($to)) {
return (new Expo)->send($message)->to($to)->push();
}
}
public function applicationRefused(ApplicationRefused $application)
{
$devices = $application->getUser()->getDevicesTokensExpo();
$applicationRepo = $this->applicationRepository->findOneBy(['id' => $application->getId()]);
switch ($application->getUser()->getNotificationType()) {
case BaseUser::NOTIFICATION_MAIL:
$this->sendMailApplicationRefused($applicationRepo);
break;
case BaseUser::NOTIFICATION_PUSH:
if ($devices) $this->sendPushApplicationRefused($devices, $applicationRepo);
break;
case BaseUser::NOTIFICATION_PUSH_MAIL:
$this->sendMailApplicationRefused($applicationRepo);
if ($devices) $this->sendPushApplicationRefused($devices, $applicationRepo);
break;
}
return $application;
}
}