src/Mail/Service/SwiftMailService.php
<?php declare(strict_types=1);
namespace VSV\GVQ_API\Mail\Service;
use Swift_Attachment;
use Swift_Mailer;
use Swift_Message;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Twig_Environment;
use VSV\GVQ_API\Common\ValueObjects\Language;
use VSV\GVQ_API\Mail\Models\Sender;
use VSV\GVQ_API\Registration\Models\Registration;
class SwiftMailService implements MailService
{
/**
* @var Swift_Mailer
*/
private $swiftMailer;
/**
* @var Twig_Environment
*/
private $twig;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var UrlGeneratorInterface
*/
private $urlGenerator;
/**
* @var string
*/
private $projectDir;
/**
* @var Sender[]
*/
private $senders;
/**
* @param Swift_Mailer $swiftMailer
* @param Twig_Environment $twig
* @param TranslatorInterface $translator
* @param UrlGeneratorInterface $urlGenerator
* @param Sender ...$senders
*/
public function __construct(
Swift_Mailer $swiftMailer,
Twig_Environment $twig,
TranslatorInterface $translator,
UrlGeneratorInterface $urlGenerator,
string $projectDir,
Sender ...$senders
) {
$this->swiftMailer = $swiftMailer;
$this->twig = $twig;
$this->translator = $translator;
$this->urlGenerator = $urlGenerator;
$this->projectDir = $projectDir;
$this->senders = $senders;
}
/**
* @inheritdoc
* @throws \Twig_Error
*/
public function sendActivationMail(Registration $registration): void
{
$subjectId = 'Activation.mail.subject';
$templateName = 'activate';
$templateParameters = $this->generateAccountChangeTemplateParameters(
$registration,
'accounts_view_activate'
);
$message = $this->generateMessage($registration, $subjectId, $templateName, $templateParameters);
$this->swiftMailer->send($message);
}
/**
* @inheritdoc
* @throws \Twig_Error
*/
public function sendPasswordRequestMail(Registration $registration): void
{
$subjectId = 'Password.reset.mail.subject';
$templateName = 'request_password';
$templateParameters = $this->generateAccountChangeTemplateParameters(
$registration,
'accounts_view_reset_password'
);
$message = $this->generateMessage($registration, $subjectId, $templateName, $templateParameters);
$this->swiftMailer->send($message);
}
/**
* @inheritdoc
* @throws \Twig_Error
*/
public function sendWelcomeMail(Registration $registration): void
{
$subjectId = 'Welcome.mail.subject';
$templateName = 'welcome';
$templateParameters = $this->generateWelcomeTemplateParameters($registration);
$message = $this->generateMessage($registration, $subjectId, $templateName, $templateParameters);
$this->swiftMailer->send($message);
}
/**
* @inheritdoc
* @throws \Twig_Error
*/
public function sendKickOffMailAfterLaunch(Registration $registration): void
{
$subjectId = 'Kickoff.after.launch.mail.subject';
$templateName = 'kick_off_after_launch';
$templateParameters = $this->generateKickOffTemplateParameters($registration);
$message = $this->generateMessage($registration, $subjectId, $templateName, $templateParameters);
// @codeCoverageIgnoreStart
$documentName = $this->getKickOffDocumentName($registration);
if ($registration->getUser()->getLanguage()->toNative() === Language::FR) {
$documentPath = $this->projectDir . '/public/documents/fr/'.$documentName;
} else {
$documentPath = $this->projectDir . '/public/documents/nl/'.$documentName;
}
// @codeCoverageIgnoreEnd
$message->attach(Swift_Attachment::fromPath($documentPath));
$this->swiftMailer->send($message);
}
/**
* @inheritdoc
* @throws \Twig_Error
*/
public function sendKickOffMail(Registration $registration): void
{
$subjectId = 'Kickoff.mail.subject';
$templateName = 'kick_off';
$templateParameters = $this->generateKickOffTemplateParameters($registration);
$message = $this->generateMessage($registration, $subjectId, $templateName, $templateParameters);
// @codeCoverageIgnoreStart
$documentName = $this->getKickOffDocumentName($registration);
if ($registration->getUser()->getLanguage()->toNative() === Language::FR) {
$documentPath = $this->projectDir . '/public/documents/fr/'.$documentName;
} else {
$documentPath = $this->projectDir . '/public/documents/nl/'.$documentName;
}
// @codeCoverageIgnoreEnd
$message->attach(Swift_Attachment::fromPath($documentPath));
$this->swiftMailer->send($message);
}
/**
* @param Registration $registration
* @param string $subjectId
* @param string $templateName
* @param array $templateParameters
* @return Swift_Message
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
private function generateMessage(
Registration $registration,
string $subjectId,
string $templateName,
array $templateParameters
): Swift_Message {
$sender = $this->getSenderForLanguage($registration);
return (new Swift_Message())
->setFrom(
$sender->getEmail()->toNative(),
$sender->getName()->toNative()
)
->setTo(
$registration->getUser()->getEmail()->toNative(),
$registration->getUser()->getFirstName()->toNative().' '.
$registration->getUser()->getLastName()->toNative()
)
->setSubject(
$this->generateSubject($registration, $subjectId)
)
->setBody(
$this->twig->render(
$this->getHtmlTemplate(
$registration->getUser()->getLanguage(),
$templateName
),
$templateParameters
),
'text/html'
);
}
/**
* @param Registration $registration
* @return Sender
*/
private function getSenderForLanguage(Registration $registration): Sender
{
$senderForLanguage = $this->senders[0];
foreach ($this->senders as $sender) {
if ($registration->getUser()->getLanguage()->equals($sender->getLanguage())) {
$senderForLanguage = $sender;
}
}
return $senderForLanguage;
}
/**
* @param Registration $registration
* @param string $subjectId
* @return string
*/
private function generateSubject(Registration $registration, string $subjectId): string
{
return $this->translator->trans(
$subjectId,
[],
null,
$registration->getUser()->getLanguage()->toNative()
);
}
/**
* @param Language $language
* @param string $templateName
* @return string
*/
private function getHtmlTemplate(Language $language, string $templateName): string
{
return 'mails/'.$templateName.'.'.$language->toNative().'.html.twig';
}
/**
* @param Language $language
* @param string $templateName
* @return string
*/
private function getTextTemplate(Language $language, string $templateName): string
{
return 'mails/'.$templateName.'.'.$language->toNative().'.text.twig';
}
/**
* @param Registration $registration
* @param string $routeName
* @return array
*/
private function generateAccountChangeTemplateParameters(Registration $registration, string $routeName): array
{
return [
'registration' => $registration,
'activationUrl' => $this->generateUrlWithSuffix($registration, $routeName),
];
}
/**
* @param Registration $registration
* @return array
*/
private function generateWelcomeTemplateParameters(Registration $registration): array
{
return [
'registration' => $registration,
'loginUrl' => $this->generateLoginUrl($registration),
];
}
/**
* @param Registration $registration
* @return array
*/
private function generateKickOffTemplateParameters(Registration $registration): array
{
return [
'registration' => $registration,
'loginUrl' => $this->generateLoginUrl($registration),
'documentsUrl' => $this->generateDocumentsUrl($registration),
'documentUrl' => $this->generateKickOffDocumentUrl($registration),
];
}
/**
* @param Registration $registration
* @param string $routeName
* @return string
*/
private function generateUrlWithSuffix(Registration $registration, string $routeName): string
{
return $this->urlGenerator->generate(
$routeName,
[
'_locale' => $registration->getUser()->getLanguage()->toNative(),
'urlSuffix' => $registration->getUrlSuffix()->toNative(),
],
UrlGeneratorInterface::ABSOLUTE_URL
);
}
private function generateAbsoluteUrl(Registration $registration, $name, $parameters = [])
{
$lang = $registration->getUser()->getLanguage()->toNative();
$parameters['_locale'] = $lang;
$oldHost = null;
if ($lang == Language::FR) {
$oldHost = $this->urlGenerator->getContext()->getHost();
$this->urlGenerator->getContext()->setHost('app.quizdelaroute.be');
}
$url = $this->urlGenerator->generate(
$name,
$parameters,
UrlGeneratorInterface::ABSOLUTE_URL
);
if ($oldHost) {
$this->urlGenerator->getContext()->setHost($oldHost);
}
return $url;
}
/**
* @param Registration $registration
* @return string
*/
private function generateLoginUrl(Registration $registration): string
{
return $this->generateAbsoluteUrl($registration, 'accounts_view_login');
}
/**
* @param Registration $registration
* @return string
*/
private function getKickOffDocumentName(Registration $registration): string
{
// @codeCoverageIgnoreStart
if ($registration->getUser()->getLanguage()->toNative() === Language::FR) {
return 'briefing_entreprise.pdf';
} else {
return 'Briefing voor bedrijven 2021.pdf';
}
// @codeCoverageIgnoreEnd
}
/**
* @param Registration $registration
* @return string
*/
private function generateDocumentsUrl(Registration $registration): string
{
return $this->generateAbsoluteUrl($registration, 'documents');
}
/**
* @param Registration $registration
* @return string
*/
private function generateKickOffDocumentUrl(Registration $registration): string
{
$documentName = $this->getKickOffDocumentName($registration);
return $this->generateAbsoluteUrl(
$registration,
'documents_kickoff',
[
'document' => $documentName,
]
);
}
}