<?php
namespace FMT\Domain\EventSubscriber;
use Exception;
use FMT\Data\Entity\User;
use FMT\Data\Entity\UserNotifications;
use FMT\Domain\Event\BookstoreApiNotificationEvent;
use FMT\Domain\Repository\UserNotificationsRepositoryInterface;
use FMT\Infrastructure\Helper\NotificationHelper;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;
class BookstoreApiNotificationSubscriber implements EventSubscriberInterface
{
private const BOOKSTORE_FAILS_TITLE = 'fmt.notifications.api_fails';
private UserNotificationsRepositoryInterface $userNotificationsRepository;
private TranslatorInterface $translator;
private LoggerInterface $logger;
private Environment $parser;
public function __construct(
UserNotificationsRepositoryInterface $userNotificationsRepository,
TranslatorInterface $translator,
LoggerInterface $logger,
Environment $parser
) {
$this->userNotificationsRepository = $userNotificationsRepository;
$this->translator = $translator;
$this->logger = $logger;
$this->parser = $parser;
}
public static function getSubscribedEvents(): array
{
return [
BookstoreApiNotificationEvent::USERS_NOTIFICATION => 'onBookstoreApiFailed',
BookstoreApiNotificationEvent::ADMIN_NOTIFICATION => 'notifyAdmin'
];
}
public function onBookstoreApiFailed(BookstoreApiNotificationEvent $event)
{
$users = $event->getUsers();
$message = $this->translator->trans(
'fmt.notifications.api_fails',
['%school_name%' => $event->getBookstore()],
);
$existingNotifications = $this
->userNotificationsRepository
->findExistingNotificationsForUserByTitle($users, $message);
foreach ($users as $user) {
if ($this->hasSameNotification($user, $message, $existingNotifications)) {
continue;
}
$notification = new UserNotifications();
$notification->setUser($user);
$notification->setTitle(BookstoreApiNotificationEvent::NOTIFICATION_TITLE);
$notification->setMessage($message);
$this->userNotificationsRepository->add($notification);
}
$this->userNotificationsRepository->save();
}
public function notifyAdmin(BookstoreApiNotificationEvent $event)
{
try {
$users = $event->getUsers();
foreach ($users as $user) {
$message = $this->parser->render('@Public/emails/bookstore_blocked.email.html.twig', [
'schoolName' => $event->getBookstore(),
'user' => $user,
]);
NotificationHelper::submitFromTemplate($message, $user->getProfile()->getEmail());
}
} catch (Exception $exception) {
$this->logger->error($exception->getMessage());
}
}
/**
* @param User $user
* @param string $message
* @param array $notifications
* @return bool
*/
private function hasSameNotification(User $user, string $message, array $notifications): bool
{
foreach ($notifications as $notification) {
if ($notification->getUser() === $user
&& $notification->isSent() === false
&& $notification->getTitle() === $message) {
return true;
}
}
return false;
}
}