<?php
/**
* Created by PhpStorm.
* User: sebastiantovar
* Date: 2019-04-15
* Time: 08:51
*/
namespace App\EventSubscriber\Category;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\App\Category;
use App\Entity\App\User;
use App\Exception\InvalidArgumentException;
use App\Repository\App\CategoryRepository;
use App\Services\UtilsService;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class CategoryPostValidateSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $utilsService;
private $translator;
private $categoryRepository;
public function __construct(
TokenStorageInterface $tokenStorage,
UtilsService $utilsService,
TranslatorInterface $translator,
CategoryRepository $categoryRepository
) {
$this->tokenStorage = $tokenStorage;
$this->utilsService = $utilsService;
$this->translator = $translator;
$this->categoryRepository = $categoryRepository;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
KernelEvents::VIEW => ['prepareCategoryData', EventPriorities::POST_VALIDATE]
];
}
/**
* @param ViewEvent $event
* @throws InvalidArgumentException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function prepareCategoryData(ViewEvent $event)
{
if ($this->utilsService->isAPublicRequest($event)) {
return;
}
$category = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
$request = $event->getRequest();
if (!($category instanceof Category) ||
(Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method))
return;
$parent = $category->getParent();
if ($parent !== null && $parent !== 0)
$this->validateParent($category, $parent);
$locale = $request->getLocale();
if ($this->tokenStorage->getToken()) {
$userCurrent = $this->tokenStorage->getToken()->getUser();
if ($userCurrent instanceof User) {
$locale = $userCurrent->getLocale();
}
}
$isDuplicated = false;
if ($category->getVendor()) {
$isCategory = $this->categoryRepository->isExisted($category->getVendor(), $category->getType(), $category->getName());
if (Request::METHOD_POST === $method && $isCategory instanceof Category) {
$isDuplicated = true;
}
if (Request::METHOD_PUT === $method && $isCategory instanceof Category && $isCategory !== $category) {
$isDuplicated = true;
}
}
if ($isDuplicated) {
$response = new Response();
$response->setContent(json_encode([
'detail' => $this->translator->trans(
'category.validate.duplicated',
[],
null,
$locale
)
]));
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
$event->setResponse($response);
return;
}
}
/**
* @param Category $category
* @param Category $parent
* @throws InvalidArgumentException
*/
public function validateParent(Category $category, Category $parent)
{
if ($category->getVendor() !== $parent->getVendor()) {
throw new InvalidArgumentException(
$this->translator->trans('The vendor between the parent and the new category is not equal')
);
}
if ($category->getType() != $parent->getType()) {
throw new InvalidArgumentException(
$this->translator->trans('The type between the parent and the new category is not equal')
);
}
}
}