<?php
/**
* Created by PhpStorm.
* User: SUSAN MEDINA
* Date: 11/03/2019
* Time: 09:55 AM
*/
namespace App\EventSubscriber\Ticket;
use App\Entity\App\Category;
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\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelEvents;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Repository\App\Ticket\TicketTypeRepository;
use App\Repository\App\MediaObjectRepository;
use App\Exception\InvalidArgumentException;
use App\Exception\NotFoundException;
use App\Services\VendorService;
use App\Services\UtilsService;
use App\Entity\App\MediaObject;
use App\Entity\App\Ticket\Ticket;
class TicketPostValidateSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
private $ticketTypeRepository;
private $mediaObjectRepository;
private $vendorService;
private $utilsService;
private $translator;
public function __construct(
TokenStorageInterface $tokenStorage,
TicketTypeRepository $ticketTypeRepository,
MediaObjectRepository $mediaObjectRepository,
VendorService $vendorService,
UtilsService $utilsService,
TranslatorInterface $translator
){
$this->tokenStorage = $tokenStorage;
$this->ticketTypeRepository = $ticketTypeRepository;
$this->mediaObjectRepository = $mediaObjectRepository;
$this->vendorService = $vendorService;
$this->utilsService = $utilsService;
$this->translator = $translator;
}
/**
* @param ViewEvent $event
* @throws InvalidArgumentException
* @throws NotFoundException
*/
public function onKernelView(ViewEvent $event)
{
if ($this->utilsService->isAPublicRequest($event)) {
return;
}
$ticket = $event->getControllerResult();
$request = $event->getRequest();
$method = $request->getMethod();
if (!($ticket instanceof Ticket) ||
(Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method)
)
return;
$content = $request->getContent();
$params = json_decode($content, true);
$this->validateRequiredFields($ticket, $params, $method);
}
/**
* @param Ticket $ticket
* @param array $params
* @param string $method
* @throws InvalidArgumentException
* @throws NotFoundException
*/
protected function validateRequiredFields(Ticket $ticket, array $params, string $method)
{
if (Request::METHOD_POST === $method) {
if (!isset($params['vendor'])) {
throw new InvalidArgumentException(
$this->translator->trans('ticket.field_validate.required', ['%field%' => 'vendor'])
);
}
if (!isset($params['type'])) {
throw new InvalidArgumentException(
$this->translator->trans('ticket.field_validate.required', ['%field%' => 'type'])
);
}
}
if (!empty($params['incidenceType']) && $ticket->getIncidenceType()) {
$vendor = $ticket->getVendor();
$incidenceType = $ticket->getIncidenceType();
if ($vendor !== $incidenceType->getVendor()) {
throw new InvalidArgumentException(
$this->translator->trans('vendor.validate.does_not_belongs',
[
'%entity%' => $this->translator->trans('incidenceType'),
'%vendorName%' => $vendor->getName()
]
)
);
}
}
if (!empty($params['location']) && $ticket->getLocation()) {
$vendor = $ticket->getVendor();
$location = $ticket->getLocation();
if (!in_array($location, $vendor->getLocations()->toArray())) {
throw new InvalidArgumentException(
$this->translator->trans('vendor.validate.does_not_belongs',
[
'%entity%' => $this->translator->trans('location.title'),
'%vendorName%' => $vendor->getName()
]
)
);
}
}
if (!empty($params['category']) && $ticket->getCategory()) {
if ($ticket->getCategory()->getVendor() !== $ticket->getVendor()) {
throw new InvalidArgumentException(
$this->translator->trans('vendor.validate.does_not_belongs',
[
'%entity%' => $this->translator->trans('category.title'),
'%vendorName%' => $ticket->getVendor()->getName()
]
)
);
}
if ($ticket->getCategory()->getType() !== Category::TYPE_TASK) {
throw new InvalidArgumentException(
$this->translator->trans('category.validate.type_not_allowed',
[
'%type%' => $ticket->getCategory()->getType(),
'%typeAllowed%' => Category::TYPE_TASK
]
)
);
}
}
if(isset($params['mediaContent']) &&
is_array($params['mediaContent']) &&
count($params['mediaContent']) > 0
){
foreach ($ticket->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->getTicket() !== null && $media->getTicket() !== $ticket) {
throw new InvalidArgumentException(
$this->translator->trans('mediaObject.validate.does_not_belongs',
[
'%mediaId%' => $mediaId,
'%entity%' => $this->translator->trans("ticket.type.{$media->getTicket()->getType()->getName()}")
]
)
);
}
if ($media->getType() !== MediaObject::TYPE_TICKET) {
throw new InvalidArgumentException(
$this->translator->trans(
'mediaObject.validate.type_not_allowed',
[
'%mediaId%' => $mediaId,
'%mediaType%' => $media->getType(),
'%mediaTypeAvailable%' => MediaObject::TYPE_TICKET
]
)
);
}
}
}
//Validamos los campos de los mantenimientos programados
$scheduledTask = $this->ticketTypeRepository->findOneBy(['name' => 'scheduled_task']);
if ($ticket->getType() === $scheduledTask) {
$validateReminderDate = false;
$validateReminderDateToday = false;
if (isset($params['repeat']) && $params['repeat']) {
$frequency = ['week', 'month', 'year'];
$week = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
if (!isset($params['frequency']) || is_null($params['frequency'])) {
throw new InvalidArgumentException(
$this->translator->trans(
'general.validate.required_allowed',
[
'%field%' => 'frequency',
'%allowedValue%' => implode(', ', $frequency)
]
)
);
}
if ($params['frequency'] == 'week') {
if (!isset($params['frequencyWeek']) ||
is_null($params['frequencyWeek'])
) {
throw new InvalidArgumentException(
$this->translator->trans(
'general.validate.required_allowed',
[
'%field%' => 'frequencyWeek',
'%allowedValue%' => implode(', ', $week)
]
)
);
}
if (is_array($params['frequencyWeek'])) {
foreach ($params['frequencyWeek'] as $frequencyWeek) {
if (!in_array($frequencyWeek, array_keys($week))) {
throw new InvalidArgumentException(
$this->translator->trans(
'general.validate.value_not_allowed',
[
'%value%' => $frequencyWeek
]
)
);
}
}
}
}
if ($params['frequency'] == 'week') {
$validateReminderDateToday = true;
}
if ($params['frequency'] == 'month' || $params['frequency'] == 'year') {
$validateReminderDate = true;
}
} else {
$validateReminderDate = true;
$validateReminderDateToday = true;
}
if ($validateReminderDate) {
if (!isset($params['reminderDate']) && is_null($params['reminderDate'])) {
throw new InvalidArgumentException(
$this->translator->trans(
'general.validate.required_not_null',
[
'%field%' => 'reminderDate'
]
)
);
}
}
if ($validateReminderDateToday) {
if (!isset($params['reminderDate']) && !is_null($params['reminderDate']) &&
$params['reminderDate']->format('Y-m-d') < date('Y-m-d')
) {
throw new InvalidArgumentException(
$this->translator->trans(
'general.validate.date_must_be_greater',
[
'%field%' => 'repeatDateEnd',
'%dateCompare%' => date('d-m-Y')
]
)
);
}
}
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::POST_VALIDATE]
];
}
}