<?php
/**
* Created by PhpStorm.
* User: SUSAN MEDINA
* Date: 26/04/2019
* Time: 11:50 AM
*/
namespace App\EventSubscriber\Location;
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 ApiPlatform\Core\EventListener\EventPriorities;
use App\Exception\InvalidArgumentException;
use App\Exception\NotFoundException;
use App\Repository\App\MediaObjectRepository;
use App\Repository\App\MaintenanceElementRepository;
use App\Repository\App\ResourceRepository;
use App\Repository\App\CategoryRepository;
use App\Repository\App\UserRepository;
use App\Repository\App\VendorStaffRepository;
use App\Entity\App\Location;
use App\Entity\App\MediaObject;
use App\Entity\App\Category;
use App\Entity\App\User;
use App\Entity\App\VendorStaff;
class LocationPostValidateSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $request;
private $mediaObjectRepository;
private $elementRepository;
private $resourceRepository;
private $categoryRepository;
private $userRepository;
private $vendorStaffRepository;
private $translator;
public function __construct(
MediaObjectRepository $mediaObjectRepository,
MaintenanceElementRepository $elementRepository,
ResourceRepository $resourceRepository,
CategoryRepository $categoryRepository,
UserRepository $userRepository,
VendorStaffRepository $vendorStaffRepository,
TokenStorageInterface $tokenStorage,
TranslatorInterface $translator
){
$this->tokenStorage = $tokenStorage;
$this->mediaObjectRepository = $mediaObjectRepository;
$this->elementRepository = $elementRepository;
$this->resourceRepository = $resourceRepository;
$this->categoryRepository = $categoryRepository;
$this->userRepository = $userRepository;
$this->vendorStaffRepository = $vendorStaffRepository;
$this->translator = $translator;
}
/**
* @param ViewEvent $event
* @throws InvalidArgumentException
* @throws NotFoundException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function onKernelView(ViewEvent $event)
{
$location = $event->getControllerResult();
$this->request = $event->getRequest();
$method = $this->request->getMethod();
if (!($location instanceof Location) ||
(Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method)
)
return;
$content = $this->request->getContent();
$params = json_decode($content, true);
if(isset($params['mediaContent']) &&
is_array($params['mediaContent']) &&
count($params['mediaContent']) > 0
){
foreach ($location->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
]
)
);
}
if ($media->getLocation() !== null &&
$media->getLocation() !== $location){
throw new InvalidArgumentException(
$this->translator->trans('mediaObject.validate.does_not_belongs',
[
'%mediaId%' => $mediaId,
'%entity%' => $this->translator->trans('location.name')
]
)
);
}
if ($media->getType() !== MediaObject::TYPE_LOCATION) {
throw new InvalidArgumentException(
$this->translator->trans(
'mediaObject.validate.type_not_allowed',
[
'%mediaId%' => $mediaId,
'%mediaType%' => $media->getType(),
'%mediaTypeAvailable%' => MediaObject::TYPE_LOCATION
]
)
);
}
}
}
if(isset($params['maintenanceElements']) && is_array($params['maintenanceElements'])){
foreach ($params['maintenanceElements'] as $element) {
if (isset($element['id'])) {
$maintenanceElement = $this->elementRepository->findOneById($element['id']);
if ($maintenanceElement['vendorId'] !== $location->getVendor()->getId()) {
throw new InvalidArgumentException(
$this->translator->trans('vendor.validate.does_not_belongs',
[
'%entity%' => $this->translator->trans('maintenanceElement.title'),
'%vendorName%' => $location->getVendor()->getName()
]
)
);
}
if ($maintenanceElement['locationId'] !== null &&
$maintenanceElement['locationId'] !== $location->getId()) {
throw new InvalidArgumentException(
$this->translator->trans(
'This entity has belong to another entity already',
[
'%entity1%' => $this->translator->trans('maintenanceElement.title'),
'%entity2%' => $this->translator->trans('location.title'),
'%entityId1%' => $element['id']
]
)
);
}
}
}
}
if (isset($params['resources']) && is_array($params['resources'])) {
foreach ($params['resources'] as $resource) {
if (isset($resource['id'])) {
$getResource = $this->resourceRepository->findOneById($resource['id']);
if ($getResource['vendorId'] !== $location->getVendor()->getId()) {
throw new InvalidArgumentException(
$this->translator->trans('vendor.validate.does_not_belongs',
[
'%entity%' => $this->translator->trans('resource.title'),
'%vendorName%' => $location->getVendor()->getName()
]
)
);
}
if ($getResource['locationId'] !== null &&
$getResource['locationId'] !== $location->getId()) {
throw new InvalidArgumentException(
$this->translator->trans(
'This entity has belong to another entity already',
[
'%entity1%' => $this->translator->trans('resource.title'),
'%entity2%' => $this->translator->trans('location.title'),
'%entityId1%' => $resource['id']
]
)
);
}
}
}
}
if(isset($params['categories']) && is_array($params['categories'])){
foreach ($params['categories'] as $field) {
if (isset($field['id'])) {
$category = $this->categoryRepository->find($field['id']);
if ($category->getVendor() !== $location->getVendor()) {
throw new InvalidArgumentException(
$this->translator->trans('vendor.validate.does_not_belongs',
[
'%entity%' => $this->translator->trans('category.title'),
'%vendorName%' => $location->getVendor()->getName()
]
)
);
}
if ($category->getType() !== Category::TYPE_LOCATION) {
throw new InvalidArgumentException(
$this->translator->trans('category.validate.type_not_allowed',
[
'%type%' => $category->getType(),
'%typeAllowed%' => Category::TYPE_LOCATION
]
)
);
}
}
}
}
if (isset($params['users']) && count($params['users']) > 0) {
foreach ($params['users'] as $userId) {
if (is_integer($userId)) {
$user = $this->userRepository->find($userId);
if (!$user instanceof User) {
throw new NotFoundException($this->translator->trans('User not found'));
}
$vendorStaff = $this->vendorStaffRepository->findOneBy(
[
'user' => $user,
'vendor' => $location->getVendor()
]
);
if (!$vendorStaff instanceof VendorStaff) {
throw new InvalidArgumentException(
$this->translator->trans(
'This entity does not belong to vendor',
[
'%entity%' => $this->translator->trans('user'),
'%entityId%' => $userId
]
)
);
}
} else {
throw new InvalidArgumentException(
$this->translator->trans('invalid field format', ['%field%' => 'users'])
);
}
}
}
if($location->getLng() && $location->getLat()) {
$location->setPoint("POINT({$location->getLng()} {$location->getLat()})");
}
return;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::POST_VALIDATE]
];
}
}