<?php
namespace App\EventSubscriber\Validation;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Company\Company;
use App\Entity\User\Address\Delivery;
use App\Entity\User\Address\Home;
use App\Entity\User\User;
use Doctrine\ORM\EntityManagerInterface;
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 Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
final class UserSubscriber implements EventSubscriberInterface
{
private $user;
private AuthorizationCheckerInterface $authChecker;
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $em;
/**
* UserSubscriber constructor.
* @param TokenStorageInterface $tokenStorage
* @param AuthorizationCheckerInterface $authChecker
* @param EntityManagerInterface $em
*/
public function __construct(
TokenStorageInterface $tokenStorage,
AuthorizationCheckerInterface $authChecker,
EntityManagerInterface $em)
{
if (!$tokenStorage->getToken()) {
return;
}
$this->user = $tokenStorage->getToken()->getUser();
$this->authChecker = $authChecker;
$this->em = $em;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => [
['removeRoles', EventPriorities::PRE_VALIDATE],
['addCompany', EventPriorities::PRE_VALIDATE],
['addAddress', EventPriorities::PRE_VALIDATE],
],
];
}
// set default company
public function addAddress(ViewEvent $event)
{
$userEntity = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$userEntity instanceof User || !in_array($method, [Request::METHOD_POST, Request::METHOD_PUT])) {
return;
}
$this->setHome($event, $userEntity);
$this->setDelivery($event, $userEntity);
}
// set default company
public function addCompany(ViewEvent $event)
{
$userEntity = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$userEntity instanceof User || !in_array($method, [Request::METHOD_POST, Request::METHOD_PUT])) {
return;
}
// no restrictions for admin
if ($this->authChecker->isGranted('ROLE_ADMIN', $this->user)) {
return;
}
if ($userEntity->getCompany() instanceof Company) {
return;
}
if (!isset($_ENV['DEFAULT_COMPANY_UUID']) || !$_ENV['DEFAULT_COMPANY_UUID']) {
throw new \Exception('DEFAULT_COMPANY_UUID env var is missing', 500);
}
// set default company if not provided
$company = $this->em->getRepository(Company::class)->find($_ENV['DEFAULT_COMPANY_UUID']);
if (!$company instanceof Company) {
throw new \Exception(
sprintf(
'Default Company %s set in env var DEFAULT_COMPANY_UUID not found',
$_ENV['DEFAULT_COMPANY_UUID']
),
500
);
}
$userEntity->setCompany($company);
}
// set default roles on account creation without ROLE_ADMIN
public function removeRoles(ViewEvent $event)
{
$userEntity = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$userEntity instanceof User || !in_array($method, [Request::METHOD_POST, Request::METHOD_PUT])) {
return;
}
// no restrictions for admin
if ($this->authChecker->isGranted('ROLE_ADMIN', $this->user)) {
return;
}
//do something before validate user
}
private function setHome(ViewEvent $event, User $userEntity)
{
$addresses = json_decode($event->getRequest()->getContent(), true)['addressesHome'] ?? [];
foreach ($addresses as $address) {
$newAddress = new Home();
$newAddress
->setStreet($address['street'] ?? '')
->setComplement($address['complement'] ?? '')
->setPostalCode($address['postalCode'] ?? '')
->setCity($address['city'] ?? '')
->setFavorite($address['favorite'] ?? false)
->setUser($userEntity)
;
$userEntity->addAddressHome($newAddress);
}
}
private function setDelivery(ViewEvent $event, User $userEntity)
{
$addresses = json_decode($event->getRequest()->getContent(), true)['addressesDelivery'] ?? [];
foreach ($addresses as $address) {
$newAddress = new Delivery();
$newAddress
->setFirstName($address['firstName'] ?? '')
->setLastName($address['lastName'] ?? '')
->setStreet($address['street'] ?? '')
->setComplement($address['complement'] ?? '')
->setPostalCode($address['postalCode'] ?? '')
->setCity($address['city'] ?? '')
->setPhoneNumber($address['phoneNumber'] ?? null)
->setFavorite($address['favorite'] ?? false)
->setExtraInformation($address['extraInformation'] ?? '')
->setUser($userEntity)
;
$userEntity->addAddressDelivery($newAddress);
}
}
}