<?php
namespace App\EventSubscriber;
use ApiPlatform\Symfony\EventListener\EventPriorities;
use App\Entity\Employee;
use App\Entity\User;
use App\Service\Message;
use JetBrains\PhpStorm\ArrayShape;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use function json_decode;
use function str_contains;
final class NewAccountSubscriber implements EventSubscriberInterface
{
/** @var string The relative path inside templates/messages without any extensions */
private const TEMPLATE = 'user/new-account';
public function __construct(
private readonly TokenStorageInterface $tokenStorage,
private readonly Message $messageService,
)
{
}
#[ArrayShape([KernelEvents::VIEW => "array"])]
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['sendMessage', EventPriorities::POST_WRITE],
];
}
public function sendMessage(ViewEvent $event): void
{
$entity = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
# POST methods are used to create instances, and we are only interested in new users
if ((!$entity instanceof User && !$entity instanceof Employee) || $method !== Request::METHOD_POST || str_contains($event->getRequest()->getPathInfo(), 'resetPassword')) {
return;
}
$requestBody = json_decode($event->getRequest()->getContent(), true);
$email = null;
$password = null;
if ($entity instanceof User) {
$email = $entity->getUsername();
$password = $requestBody['password'];
}
if ($entity instanceof Employee) {
$email = $entity->getUser()->getUsername();
$password = $requestBody['user']['password'];
}
if (empty($email) || empty($password)) {
return;
}
$message = $this->messageService
->withRecipient($entity)
->withSubject('You have a new account')
->withTemplate(self::TEMPLATE)
->withTemplateData([
'email' => $email,
'password' => $password,
'loginUrl' => $event->getRequest()->server->get('HTTP_ORIGIN') . '/admin/#/login',
])
->withSensitiveData([$password]);
$currentUser = $this->tokenStorage->getToken()->getUser();
if ($currentUser instanceof User) {
$message = $message->withCurrentUser($currentUser);
}
$message->send();
}
}