<?php
namespace App\EventSubscriber\Task;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\Translation\TranslatorInterface;
use Doctrine\ORM\EntityManagerInterface;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Repository\App\Task\WorkerBudgetRepository;
use App\Repository\App\Task\TaskRepository;
use App\Repository\App\RoleRepository;
use App\Exception\AccessDeniedException;
use App\Exception\NotFoundException;
use App\Services\VendorService;
use App\Services\UtilsService;
use App\Entity\App\Task\TaskStatusLog;
use App\Entity\App\Task\Task;
use App\Entity\App\User;
use App\Entity\App\Role;
use App\Entity\Chat\Chat;
class TaskPreWriteSubscriber implements EventSubscriberInterface
{
private $translator;
private $tokenStorage;
private $authorizationChecker;
private $entityManager;
private $vendorService;
private $utilsService;
private $roleRepository;
private $taskRepository;
private $workerBudgetRepository;
public function __construct(
TranslatorInterface $translator,
TokenStorageInterface $tokenStorage,
AuthorizationCheckerInterface $checker,
EntityManagerInterface $entityManager,
VendorService $vendorService,
UtilsService $utilsService,
RoleRepository $roleRepository,
TaskRepository $taskRepository,
WorkerBudgetRepository $workerBudgetRepository
) {
$this->translator = $translator;
$this->tokenStorage = $tokenStorage;
$this->authorizationChecker = $checker;
$this->entityManager = $entityManager;
$this->vendorService = $vendorService;
$this->utilsService = $utilsService;
$this->roleRepository = $roleRepository;
$this->taskRepository = $taskRepository;
$this->workerBudgetRepository = $workerBudgetRepository;
}
/**
* @param ViewEvent $event
* @throws AccessDeniedException
* @throws NotFoundException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
public function onKernelView(ViewEvent $event)
{
if ($this->utilsService->isAPublicRequest($event)) {
return;
}
$task = $event->getControllerResult();
$request = $event->getRequest();
$method = $request->getMethod();
$userCurrent = $this->tokenStorage->getToken()->getUser();
if (!($task instanceof Task) ||
(Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method && Request::METHOD_DELETE !== $method)
)
return;
if ($this->authorizationChecker->isGranted('ROLE_SUPERADMIN'))
return;
if(!($userCurrent instanceof User))
throw new NotFoundException($this->translator->trans('User current not found'));
$authorization = false;
$vendor = $task->getTicket()->getVendor();
$controlAccess = [Role::ROLE_ADMIN, Role::ROLE_TASKMASTER];
if ($this->vendorService->isUserRoleInToVendor($vendor, $userCurrent, $controlAccess)) {
$authorization = true;
}
if (Request::METHOD_POST === $method) {
$state = TaskStatusLog::STATUS_TASK_IN_PROCESS;
$task->setState($state);
$chat = new Chat();
$chat->setType(Chat::TYPE_TASK);
$this->entityManager->persist($chat);
$task->setChat($chat);
}
// restricion de capataz: solo puede editar cuando fue asignado a la tarea
// if (Request::METHOD_PUT === $method && !$authorization) {
// $controlAccess = [Role::ROLE_ADMIN, Role::ROLE_TASKMASTER];
// $role[] = $this->roleRepository->findOneBy(['name' => Role::ROLE_TASKMASTER]);
// if ($this->workerBudgetRepository->findGroupByRoles($role, $task, $userCurrent->getId()))
// $authorization = true;
// }
if (Request::METHOD_PUT === $method && !$authorization) {
$controlAccess = [Role::ROLE_ADMIN, Role::ROLE_TASKMASTER, Role::ROLE_OPERATOR];
$role[] = $this->roleRepository->findOneBy(['name' => Role::ROLE_OPERATOR]);
//operator authorization to edit the task if it belongs to this
if ($this->workerBudgetRepository->findGroupByRoles($role, $task, $userCurrent->getId())) {
$authorization = true;
}
}
if (!$authorization) {
$controlAccessTranslator = [];
foreach ($controlAccess as $roleName) {
$controlAccessTranslator[] = $this->translator->trans($roleName);
}
throw new AccessDeniedException(
$this->translator->trans('access_allowed_only_for') . (implode(', ', $controlAccessTranslator))
);
}
$task->changeDateStart = false;
$task->changeDateEnd = false;
$task->oldMaintenanceElements = [];
$task->oldConcepts = [];
if (Request::METHOD_PUT === $method) {
$oldTask = $this->taskRepository->findRangeDate($task->getId());
$task->oldMaintenanceElements = $this->taskRepository->findMaintenanceElementByTask($task);
$task->oldConcepts = $this->taskRepository->findConceptsByTask($task);
if ($oldTask['dateStart'] && $task->getDateStart() &&
$oldTask['dateStart']->format('Y-m-d') !== $task->getDateStart()->format('Y-m-d')
) {
$task->changeDateStart = true;
}
if ($oldTask['dateEnd'] && $task->getDateEnd() &&
$oldTask['dateEnd']->format('Y-m-d') !== $task->getDateEnd()->format('Y-m-d')
) {
$task->changeDateEnd = true;
}
}
return;
}
/**
* @param Task $task
* @return Task
* @throws \Exception
*/
protected function setTimezoneDate(Task &$task)
{
if ($task->getDateStart() && !is_null($task->getDateStart())) {
$date = new \DateTime();
$date->setTimestamp($task->getDateStart()->getTimestamp());
$date->setTimezone(new \DateTimeZone('UTC'));
$task->setDateStart($date);
}
if ($task->getDateEnd() && !is_null($task->getDateEnd())) {
$date = new \DateTime();
$date->setTimestamp($task->getDateEnd()->getTimestamp());
$date->setTimezone(new \DateTimeZone('UTC'));
$task->setDateEnd($date);
}
return $task;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['onKernelView', EventPriorities::PRE_WRITE]
];
}
}