src/EventSubscriber/TimeSlot/TimeSlotPreWriteSuscriber.php line 40

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber\TimeSlot;
  3. use ApiPlatform\Core\EventListener\EventPriorities;
  4. use App\Entity\App\Role;
  5. use App\Entity\App\TimeSlot\TimeSlot;
  6. use App\Entity\App\User;
  7. use App\Entity\App\Vendor;
  8. use App\Error\ErrorDataContainerForExceptions;
  9. use App\Exception\AccessDeniedException;
  10. use App\Exception\NotFoundException;
  11. use App\Repository\App\TimeSlot\TimeSlotItemRepository;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpKernel\Event\ViewEvent;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  17. use Symfony\Contracts\Translation\TranslatorInterface;
  18. class TimeSlotPreWriteSuscriber implements EventSubscriberInterface
  19. {
  20.     private $translator;
  21.     private $tokenStorage;
  22.     private $timeSlotItemRepository;
  23.     private $request;
  24.     public function __construct (TranslatorInterface $translatorTokenStorageInterface $tokenStorageTimeSlotItemRepository $timeSlotItemRepository)
  25.     {
  26.         $this->translator $translator;
  27.         $this->tokenStorage $tokenStorage;
  28.         $this->timeSlotItemRepository $timeSlotItemRepository;
  29.     }
  30.     /**
  31.      * @param ViewEvent $
  32.      * @throws \Exception
  33.      */
  34.     public function onKernelViewViewEvent $event){
  35.         $timeSlot $event->getControllerResult();
  36.         $this->request $event->getRequest();
  37.         $method $this->request->getMethod();
  38.         if(!($timeSlot instanceof TimeSlot)
  39.             || $method !== Request::METHOD_PUT && $method !== Request::METHOD_POST){
  40.                 return;
  41.         }
  42.         //Comprobamos si el usuario está logeado
  43.         $userCurrent $this->tokenStorage->getToken()->getUser();
  44.         if($userCurrent === "anon."){
  45.             throw new AccessDeniedException(
  46.                 $this->translator->trans('user no logged')
  47.             );
  48.         }
  49.         //Comprobamos que el usuario exista y no esté eliminado (softDelete)
  50.         if(!($userCurrent instanceof User))
  51.             throw new NotFoundException($this->translator->trans('User current not found'));
  52.         //Comprobamos que timeSlot pertenece al vendor del usuario logeado
  53.         $vendor=$userCurrent->getVendorStaff()[0]->getVendor();
  54.         if(!($vendor instanceof Vendor) || $vendor->getId() !== $timeSlot->getVendor()->getId()){
  55.             throw new AccessDeniedException(
  56.                 $this->translator->trans('vendor no found')
  57.             );
  58.         }
  59.         //Comprobamos el rol del usuario para determinar si tiene permiso
  60.         try {
  61.             $role $userCurrent->getVendorStaff()[0]->getRoleStaff()[0]->getRole()->getName();
  62.         }catch (\Exception $ex){
  63.             $role="";
  64.         }
  65.         if(!in_array($role, [Role::ROLE_ADMIN])){
  66.             throw new AccessDeniedException(
  67.                 $this->translator->trans('access_allowed_only_for') . $role
  68.             );
  69.         }
  70.         //Comprobamos los solapamiento horarios
  71.         $this->timeCollection($timeSlot->getTimeSlotItems()->getValues());
  72.         //Actualizamos la fecha de actualización de la franja horaria
  73.         $timeSlot->setUpdatedAt(new \DateTime("now"));
  74.     }
  75.     /**
  76.      * Creamos la estructura de tiempos por días de la semana
  77.      * @param array $itemSlotItems
  78.      * @return void
  79.      * @throws \Exception
  80.      */
  81.     private function timeCollection(Array $itemSlotItems=[]){
  82.         $daysWithConflict="";
  83.         $times=[];
  84.         $lang=null;
  85.         //Obtenemos el idioma de la request
  86.         $headerLangs $this->request->headers->get("accept-language");
  87.         if(!empty($headerLangs)){
  88.             $lang explode(",",$headerLangs)[0];
  89.         }
  90.         foreach ($itemSlotItems as $itemSlotItem){
  91.             foreach ($itemSlotItem->getDaysOfWeek() as $dayOfWeek) {
  92.                 $startTime $itemSlotItem->getStartTime();
  93.                 $endTime $itemSlotItem->getEndTime();
  94.                 if($startTime && $endTime && $startTime>$endTime) {
  95.                     $itemSlotItem->setStartTime($endTime);
  96.                     $itemSlotItem->setEndTime($startTime);
  97.                 }
  98.                 $times[$dayOfWeek]["startTime"][] = $itemSlotItem->getStartTime();
  99.                 $times[$dayOfWeek]["endTime"][] = $itemSlotItem->getEndTime();
  100.             }
  101.         }
  102.         //Buscamos solapamientos horarios por día
  103.         foreach ($times as $idx=>$dayOfWeek){
  104.             $startTime $dayOfWeek["startTime"];
  105.             $currentPos=0;
  106.             while((count($startTime) -1) >$currentPos){
  107.                 if(!$this->testTimeRange($dayOfWeek$currentPos)){
  108.                     $daysWithConflict .= $this->translator->trans("daysOfWeek." $idx, [], 'messages'$lang) . " TimeSlotPreWriteSuscriber.php";
  109.                     $startTime=[];
  110.                 }
  111.                 $currentPos++;
  112.             }
  113.         }
  114.         if(strlen($daysWithConflict)>0){
  115.             $errorText $this->translator->trans("timeSlot.timeOverlap",[],'messages',$lang);
  116.             throw new \Exception(
  117.                 new ErrorDataContainerForExceptions(array("message"=>$errorText.$daysWithConflict,"code"=>100)), 417
  118.             );
  119.         }
  120.     }
  121.     /**
  122.      * Comprobamos si solapamos los tiempos
  123.      * @param $itemCollection
  124.      * @param int $currentPos
  125.      * @return bool
  126.      */
  127.     private function testTimeRange($itemCollection$currentPos=0)
  128.     {
  129.             for ($i $currentPos $i count($itemCollection["startTime"]); $i++) {
  130.                 if ($itemCollection["startTime"][$currentPos] < $itemCollection["endTime"][$i]
  131.                     && $itemCollection["startTime"][$i] < $itemCollection["endTime"][$currentPos])
  132.                     return false;
  133.             }
  134.             return true;
  135.     }
  136.     public static function getSubscribedEvents ():array
  137.     {
  138.         return [
  139.             KernelEvents::VIEW => ['onKernelView'EventPriorities::PRE_WRITE]
  140.         ];
  141.     }
  142. }