<?php
namespace App\Subscriber\Messenger;
use App\Dictionary\ConversationMessageSource;
use App\Dictionary\MailPriority;
use App\Entity\ConversationMessage;
use App\Entity\Member;
use App\Event\Messenger\NewMessageEvent;
use App\Service\Mail\MailService;
use App\Service\Messenger\MessengerPropertyService;
use App\Service\Property\MemberPropertyService as PropertyService;
use App\Service\System\BounceService;
use App\Service\User\AccountService;
use App\Service\User\Layer\AmateurLayer;
use App\Subscriber\AbstractMailSubscriber;
use Frivol\Common\Dict\AccountStatus;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Twig\Environment;
class MailSubscriber extends AbstractMailSubscriber implements EventSubscriberInterface
{
public function __construct(
private AmateurLayer $amateurLayer,
private PropertyService $propertyService,
private BounceService $bounceService,
AccountService $accountService,
MailService $mailService,
Environment $twig,
) {
parent::__construct($accountService, $mailService, $twig);
}
public static function getSubscribedEvents(): array
{
return [
NewMessageEvent::class => [
['onNewMessage', 0],
],
];
}
/**
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
public function onNewMessage(NewMessageEvent $event)
{
$message = $event->getEntity();
$sender = $event->getSender();
$recipient = $message->getConversation()?->getPartner($sender);
if (null === $recipient
|| $recipient->isMemberOnline()
|| $this->isEmailNotificationDisabled($recipient)
|| false === $recipient->getIsActive()
|| false === in_array($recipient->getAccount()->getStatus(), [AccountStatus::ACTIVE, AccountStatus::NEW], true)
|| $this->bounceService->hasBounce($recipient->getAccount()->getEmail())
) {
return;
}
$mail = $this->createSwiftInstance($message, $recipient, $sender);
if (ConversationMessageSource::MASSMAILER === $message->getSource()) {
$priority = MailPriority::MESSENGER_NEW_MESSAGE_MASSMAILER;
// gitlab #507: only send each third message as an email to reduce mail volume
if (2 === random_int(1, 6)) {
$this->getMailService()->queueMessage($mail, $priority);
}
} else {
$priority = MailPriority::MESSENGER_NEW_MESSAGE;
$this->getMailService()->queueMessage($mail, $priority);
}
}
/**
* Returns TRUE, if the user does NOT want email notifications when he or she is offline.
*/
protected function isEmailNotificationDisabled(Member $recipient): bool
{
$prop = MessengerPropertyService::PROPERTY_MESSENGER_EMAIL_NOTIFICATION_DISABLED;
return true === $this->propertyService->getValueForMember($recipient, $prop);
}
protected function getSwiftMailSubject(Member $sender): string
{
return sprintf('Neue Nachricht von %s', $sender->getUsername());
}
/**
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
protected function createSwiftInstance(ConversationMessage $message, Member $recipient, Member $sender): \Swift_Message
{
$account = $recipient->getAccount();
$topAmateursPaginator = $this->amateurLayer->getTopAmateurs(1, 30, true, false);
$topAmateurs = $topAmateursPaginator->getIterator()->getArrayCopy();
shuffle($topAmateurs);
$subject = $this->getSwiftMailSubject($sender);
$mail = new \Swift_Message($subject);
$mail->addTo($account->getEmail());
$mail->setFrom('server@frivol.com', 'Frivol.com');
$mail->setBody($this->getTwigEnvironment()->render('emails/new-message-notification.html.twig', [
'message' => $message,
'subject' => $subject,
'sender' => $sender,
'amateurs' => array_slice($topAmateurs, 0, 4),
'recipient' => $recipient,
'login' => $this->getAccountService()->getAutologinParameter($account),
]), 'text/html');
return $mail;
}
}