<?php
namespace MedBrief\MSR\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use MedBrief\MSR\Entity\Project;
use MedBrief\MSR\Entity\ProjectClosure;
use MedBrief\MSR\Service\Notification\UserNotificationService;
use MedBrief\MSR\Service\ProjectClosure\AutoCancelServiceables;
use Override;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* This code was inspired by the API platform examples.
*
* @see https://api-platform.com/docs/v2.1/core/events/
*
* We opted for using Symfony event subscribers, rather than doctrine event subscribers, as
* they were causing weird issues when trying to invite an existing user to a matter.
*/
final readonly class ProjectClosureSubscriber implements EventSubscriberInterface
{
public function __construct(private UserNotificationService $notificationService, private AutoCancelServiceables $autoCancelServiceables)
{
}
/**
* @inheritDoc
*/
#[Override]
public static function getSubscribedEvents()
{
return [
// This event fires based on API platforms custom response generator, which hooks into the VIEW kernel event,
// and we want to fire the email after the write operation has happened.
KernelEvents::VIEW => [
['sendMatterClosureSubmissionNotification', EventPriorities::POST_WRITE],
['autoCancelServiceables', EventPriorities::POST_WRITE],
],
];
}
public function sendMatterClosureSubmissionNotification(ViewEvent $event): void
{
$projectClosure = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$projectClosure instanceof ProjectClosure || $method !== Request::METHOD_POST || $projectClosure->getProject() === null) {
return;
}
$this->notificationService->generateMatterClosureSubmissionUserNotification($projectClosure);
}
public function autoCancelServiceables(ViewEvent $event): void
{
$projectClosure = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$projectClosure instanceof ProjectClosure || $method !== Request::METHOD_POST || $projectClosure->getProject() === null) {
return;
}
// Important to note that the event must be in the exact state above before we can set the $project
$project = $projectClosure->getProject();
// Set all serviceables on the project that can be auto-cancelled to cancelled.
$this->autoCancelServiceables->setAutoCancelledByProject($project);
}
}