<?php
namespace App\EventListener\PostValidate;
use App\DTO\Invitation\SendInvitation;
use App\Service\Manager\SiteInviteManager;
use App\Service\Manager\SiteManager;
use App\Service\Manager\SitePermissionManager;
use App\Service\Manager\SitePermissionTypeManager;
use App\Service\Manager\UserManager;
use App\Service\SiteNotificationSender;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
class SendSitePermissionInvitationPostValidateTransformation implements EventSubscriberInterface
{
private $request;
private $siteManager;
private $sitePermissionTypeManager;
private $siteInviteManager;
private $userManager;
private $sitePermissionManager;
private $notificationSender;
private $entityManager;
public function __construct(
RequestStack $requestStack,
SiteNotificationSender $notificationSender,
SiteManager $siteManager,
SiteInviteManager $siteInviteManager,
UserManager $userManager,
SitePermissionTypeManager $sitePermissionTypeManager,
SitePermissionManager $sitePermissionManager,
EntityManagerInterface $entityManager
) {
$this->request = $requestStack->getCurrentRequest();
$this->siteManager = $siteManager;
$this->sitePermissionTypeManager = $sitePermissionTypeManager;
$this->siteInviteManager = $siteInviteManager;
$this->userManager = $userManager;
$this->sitePermissionManager = $sitePermissionManager;
$this->notificationSender = $notificationSender;
$this->entityManager = $entityManager;
}
public static function getSubscribedEvents()
{
return [
PostValidateListener::POST_VALIDATE_TRANSFORMATION => 'transform',
];
}
public function supportTransformation($payload, Request $request)
{
return $payload instanceof SendInvitation && $request->isMethod($request::METHOD_POST);
}
/**
* @param ViewEvent $event
*/
public function transform(ViewEvent $event)
{
/** @var SendInvitation $payload */
$payload = $event->getControllerResult();
if (!$this->supportTransformation($payload, $event->getRequest())) {
return;
}
if (null === $site = $this->siteManager->getSiteById($payload->site)) {
throw new NotFoundHttpException("No such site");
}
if (null === $permission = $this->sitePermissionTypeManager->getPermissionTypeById($payload->permission)) {
throw new NotFoundHttpException("No such permission");
}
if (null !== $this->siteInviteManager->getInviteBySiteIdAndEmail($payload->site, $payload->email)) {
throw new UnprocessableEntityHttpException("Account invite not unique");
}
$user = $this->userManager->getByEmail($payload->email);
if (null !== $user && null !== $this->sitePermissionManager->getSitePermissionBySiteAndUser($site, $user)) {
throw new UnprocessableEntityHttpException("User already has permission to this site");
}
$this->entityManager->beginTransaction();
try {
$invite = $this->siteInviteManager->create($payload->email, $site, $permission);
if (!is_null($user)) {
$this->notificationSender->sendInvitationForUserEmail($invite, $user);
} else {
$this->notificationSender->sendInvitationEmail($invite);
}
$event->setControllerResult($invite);
$this->entityManager->commit();
} catch (\Exception $exception) {
$this->entityManager->rollback();
throw $exception;
}
}
}