<?php
/**
* Created by PhpStorm.
* User: SUSAN MEDINA
* Date: 15/04/2019
* Time: 10:05 PM
*/
namespace App\EventSubscriber\MaintenanceElement;
use App\Services\UtilsService;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Exception\InvalidArgumentException;
use App\Exception\NotFoundException;
use App\Repository\App\MediaObjectRepository;
use App\Repository\App\MaintenanceElementRepository;
use App\Entity\App\MaintenanceElement;
use App\Entity\App\MediaObject;
use App\Entity\App\Category;
use App\Entity\App\User;
class MaintenanceElementPostValidateSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $request;
private $requestStack;
private $mediaObjectRepository;
private $elementRepository;
private $utilsService;
private $translator;
public function __construct(
MediaObjectRepository $mediaObjectRepository,
MaintenanceElementRepository $elementRepository,
TokenStorageInterface $tokenStorage,
UtilsService $utilsService,
TranslatorInterface $translator,
RequestStack $requestStack
){
$this->tokenStorage = $tokenStorage;
$this->mediaObjectRepository = $mediaObjectRepository;
$this->elementRepository = $elementRepository;
$this->utilsService = $utilsService;
$this->translator = $translator;
$this->requestStack = $requestStack;
}
/**
* @param ViewEvent $event
* @throws InvalidArgumentException
* @throws NotFoundException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function onKernelView(ViewEvent $event)
{
if ($this->utilsService->isAPublicRequest($event)) {
return;
}
$maintenanceElement = $event->getControllerResult();
$this->request = $event->getRequest();
$method = $this->request->getMethod();
if (!($maintenanceElement instanceof MaintenanceElement) ||
(Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method)
)
return;
$locale = $this->requestStack->getCurrentRequest()->getLocale();
$userCurrent = $this->tokenStorage->getToken()->getUser();
if ($userCurrent instanceof User) {
$locale = $userCurrent->getLocale();
}
$parent = $maintenanceElement->getParent();
if ($parent !== null && $parent !== 0)
$this->validateParent($maintenanceElement, $parent);
if($maintenanceElement->getFamily()) {
$vendor = $maintenanceElement->getVendor();
if ($maintenanceElement->getFamily()->getVendor() !== $vendor) {
throw new InvalidArgumentException(
$this->translator->trans('The family does not belongs to the vendor',
['%vendor%' => $vendor->getName()],
null,
$locale
)
);
}
if ($maintenanceElement->getFamily()->getType() !== Category::TYPE_MAINTENANCE_ELEMENT) {
throw new InvalidArgumentException(
$this->translator->trans('Family type is not allowed for this operation. Allowed',
[
'%maintenanceElement%' => $maintenanceElement->getFamily()->getType(),
'%category%' => Category::TYPE_MAINTENANCE_ELEMENT
],
null,
$locale
)
);
}
}
if ($maintenanceElement->getLocation()) {
$vendor = $maintenanceElement->getVendor();
if ($maintenanceElement->getLocation()->getVendor() !== $vendor) {
throw new InvalidArgumentException(
$this->translator->trans('vendor.validate.does_not_belongs',
[
'%entity%' => $this->translator->trans('location.title'),
'%vendorName%' => $vendor->getName()
],
null,
$locale
)
);
}
}
$content = $this->request->getContent();
$params = json_decode($content, true);
if(isset($params['mediaContent']) &&
is_array($params['mediaContent']) &&
count($params['mediaContent']) > 0
){
foreach ($maintenanceElement->getMediaContent() as $mediaId){
$media = $this->mediaObjectRepository->find($mediaId);
if (!$media instanceof MediaObject) {
throw new NotFoundException(
$this->translator->trans('general.validate.not_exists',
[
'%entityName%' => $this->translator->trans('mediaObject.name'),
'%entityId%' => $mediaId
],
null,
$locale
)
);
}
if ($media->getMaintenanceElement() !== null &&
$media->getMaintenanceElement() !== $maintenanceElement) {
throw new InvalidArgumentException(
$this->translator->trans('mediaObject.validate.does_not_belongs',
[
'%mediaId%' => $mediaId,
'%entity%' => $this->translator->trans('maintenanceElement.name')
],
null,
$locale
)
);
}
if ($media->getType() !== MediaObject::TYPE_MAINTENANCE_ELEMENT) {
throw new InvalidArgumentException(
$this->translator->trans(
'mediaObject.validate.type_not_allowed',
[
'%mediaId%' => $mediaId,
'%mediaType%' => $media->getType(),
'%mediaTypeAvailable%' => MediaObject::TYPE_MAINTENANCE_ELEMENT
],
null,
$locale
)
);
}
}
}
if(isset($params['children']) &&
is_array($params['children']) &&
count($params['children']) > 0
){
foreach ($params['children'] as $child) {
if (isset($child['id'])) {
$children = $this->elementRepository->findOneById($child['id']);
if ($children['vendorId'] !== $maintenanceElement->getVendor()->getId()) {
throw new InvalidArgumentException(
$this->translator->trans(
'The vendor between the parent and the new maintenance element is not equal',
[],
null,
$locale
)
);
}
if ($children['parentId'] && $children['parentId'] !== $maintenanceElement->getId()) {
$response = new Response();
$response->setContent(json_encode([
'detail' => $this->translator->trans(
'This children has belong to another maintenance element already',
['%id%' => $children['name']],
null,
$locale
)
]));
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
$event->setResponse($response);
return;
}
}
}
}
if($maintenanceElement->getLng() && $maintenanceElement->getLat()) {
$maintenanceElement->setPoint("POINT({$maintenanceElement->getLng()} {$maintenanceElement->getLat()})");
}
return;
}
/**
* @param MaintenanceElement $maintenanceElement
* @param MaintenanceElement $parent
* @throws InvalidArgumentException
*/
public function validateParent(MaintenanceElement $maintenanceElement, MaintenanceElement $parent)
{
if ($maintenanceElement->getVendor() !== $parent->getVendor()){
throw new InvalidArgumentException(
$this->translator->trans('The vendor between the parent and the new maintenance element is not equal')
);
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::POST_VALIDATE]
];
}
}