vendor/uvdesk/support-center-bundle/Controller/Ticket.php line 416

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\SupportCenterBundle\Controller;
  3. use Symfony\Component\HttpFoundation\Request;
  4. use Symfony\Component\HttpFoundation\Response;
  5. use Symfony\Component\EventDispatcher\GenericEvent;
  6. use Symfony\Component\Validator\Constraints\DateTime;
  7. use Symfony\Component\Security\Core\User\UserInterface;
  8. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  9. use Webkul\UVDesk\SupportCenterBundle\Form\Ticket as TicketForm;
  10. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  11. use Webkul\UVDesk\CoreFrameworkBundle\Workflow\Events as CoreWorkflowEvents;
  12. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  13. use Webkul\UVDesk\CoreFrameworkBundle\Services\UserService;
  14. use Webkul\UVDesk\CoreFrameworkBundle\Services\UVDeskService;
  15. use Webkul\UVDesk\CoreFrameworkBundle\Services\TicketService;
  16. use Webkul\UVDesk\CoreFrameworkBundle\Services\CustomFieldsService;
  17. use Webkul\UVDesk\CoreFrameworkBundle\FileSystem\FileSystem;
  18. use Symfony\Contracts\Translation\TranslatorInterface;
  19. use Webkul\UVDesk\CoreFrameworkBundle\Services\ReCaptchaService;
  20. use Symfony\Component\DependencyInjection\ContainerInterface;
  21. use Symfony\Component\HttpKernel\KernelInterface;
  22. use Webkul\UVDesk\SupportCenterBundle\Entity as SupportEntites;
  23. use Webkul\UVDesk\CoreFrameworkBundle\Entity as CoreEntites;
  24. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Ticket as TicketEntity
  25. class Ticket extends AbstractController
  26. {
  27.     private $userService;
  28.     private $eventDispatcher;
  29.     private $translator;
  30.     private $uvdeskService;
  31.     private $ticketService;
  32.     private $CustomFieldsService;
  33.     private $recaptchaService;
  34.     private $kernel;
  35.     public function __construct(UserService $userServiceUVDeskService $uvdeskService,EventDispatcherInterface $eventDispatcherTranslatorInterface $translatorTicketService $ticketServiceCustomFieldsService $CustomFieldsServiceReCaptchaService $recaptchaServiceKernelInterface $kernel)
  36.     {
  37.         $this->userService $userService;
  38.         $this->eventDispatcher $eventDispatcher;
  39.         $this->translator $translator;
  40.         $this->uvdeskService $uvdeskService;
  41.         $this->ticketService $ticketService;
  42.         $this->CustomFieldsService $CustomFieldsService;
  43.         $this->recaptchaService $recaptchaService;
  44.         $this->kernel $kernel;
  45.     }
  46.     protected function isWebsiteActive()
  47.     {
  48.         $entityManager $this->getDoctrine()->getManager();
  49.         $website $entityManager->getRepository(CoreEntites\Website::class)->findOneByCode('knowledgebase');
  50.         if (!empty($website)) {
  51.             $knowledgebaseWebsite $entityManager->getRepository(SupportEntites\KnowledgebaseWebsite::class)->findOneBy(['website' => $website->getId(), 'status' => 1]);
  52.             
  53.             if (!empty($knowledgebaseWebsite) && true == $knowledgebaseWebsite->getIsActive()) {
  54.                 return true;
  55.             }
  56.         }
  57.         $this->noResultFound();
  58.     }
  59.     /**
  60.      * If customer is playing with url and no result is found then what will happen
  61.      * @return
  62.      */
  63.     protected function noResultFound()
  64.     {
  65.         throw new NotFoundHttpException('Not found !');
  66.     }
  67.     public function ticketadd(Request $requestContainerInterface $container)
  68.     {
  69.         $loggedUser $this->get('security.token_storage')->getToken()->getUser();
  70.         
  71.         // Dump the $loggedUser value to the console or debug output
  72.         // dump($loggedUser->getId());
  73.         // exit;
  74.           // Ensure the logged-in user is not 'anon.'
  75.             if (!empty($loggedUser) && $loggedUser != 'anon.') {
  76.         
  77.                 // Get the EntityManager
  78.                 $em $this->getDoctrine()->getManager();
  79.         
  80.                 // Fetch all tickets for the logged-in user with status_id 4 (Resolved)
  81.                 $resolvedTickets $em->getRepository(TicketEntity::class)->findBy([
  82.                     'customer' => $loggedUser,  // Make sure this maps to 'customer_id'
  83.                     'status' => // Assuming '4' is the status_id for "Resolved"
  84.                 ]);
  85.                 
  86.                 
  87.                 // If there are resolved tickets, restrict ticket creation
  88.                 if (!empty($resolvedTickets)) {
  89.                         $ticketCount count($resolvedTickets);
  90.                     // Get the ticket IDs
  91.                     $ticketIds array_map(function ($ticket) {
  92.                         return $ticket->getId(); // Assuming 'getId()' method fetches the ticket ID
  93.                     }, $resolvedTickets);
  94.                 
  95.                     // Convert ticket IDs to a comma-separated string
  96.                     $ticketIdsString implode(', '$ticketIds);
  97.                 
  98.                     // Add flash message with ticket IDs
  99.                     $this->addFlash('warning'$this->translator->trans("You have %count% tickets with status 'Resolved' (Ticket IDs: %ticket_ids%). Please update their status to 'Close' before creating a new ticket.", ['%count%' => $ticketCount,'%ticket_ids%' => $ticketIdsString]));
  100.                 
  101.                     // Redirect to ticket list
  102.                     return $this->redirect($this->generateUrl('helpdesk_customer_ticket_collection'));
  103.                 }
  104.             }
  105.         
  106.         // return $this->redirect($this->generateUrl('helpdesk_customer_ticket_collection')); 
  107.         
  108.         $this->isWebsiteActive();
  109.         
  110.         $formErrors $errors = array();
  111.         $em $this->getDoctrine()->getManager();
  112.         $website $em->getRepository(CoreEntites\Website::class)->findOneByCode('knowledgebase');
  113.         $websiteConfiguration $this->uvdeskService->getActiveConfiguration($website->getId());
  114.         if (!$websiteConfiguration || !$websiteConfiguration->getTicketCreateOption() || ($websiteConfiguration->getLoginRequiredToCreate() && !$this->getUser())) {
  115.             return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  116.         }
  117.         
  118.         
  119.         $loggedUser $this->get('security.token_storage')->getToken()->getUser();
  120.     
  121.         if (!empty($loggedUser) && $loggedUser != 'anon.') {
  122.             // Check if the user has any resolved tickets
  123.             $resolvedTicket $em->getRepository(CoreEntites\Ticket::class)->findOneBy([
  124.                 'customer' => $loggedUser,
  125.                 'status' => 'Resolved' // Make sure this matches your actual status field value
  126.             ]);
  127.     
  128.             if ($resolvedTicket) {
  129.                 $this->addFlash('warning'$this->translator->trans("You cannot create a new ticket because you have a resolved ticket."));
  130.                 return $this->redirect($this->generateUrl('helpdesk_customer_ticket_collection')); // Redirect to ticket list
  131.             }
  132.         }
  133.         
  134.         $post $request->request->all();
  135.         $recaptchaDetails $this->recaptchaService->getRecaptchaDetails();
  136.         if($request->getMethod() == "POST") {
  137.             if ($recaptchaDetails && $recaptchaDetails->getIsActive() == true && $this->recaptchaService->getReCaptchaResponse($request->request->get('g-recaptcha-response'))
  138.             ) {
  139.                 $this->addFlash('warning'$this->translator->trans("Warning ! Please select correct CAPTCHA !"));
  140.             } else {
  141.                 if($_POST) {
  142.                     $error false;
  143.                     $message '';
  144.                     $ticketType $em->getRepository(CoreEntites\TicketType::class)->find($request->request->get('type'));
  145.                     
  146.                     if($request->files->get('customFields') && !$this->CustomFieldsService->validateAttachmentsSize($request->files->get('customFields'))) {
  147.                         $error true;
  148.                         $this->addFlash(
  149.                                 'warning',
  150.                                 $this->translator->trans("Warning ! Files size can not exceed %size% MB", [
  151.                                     '%size%' => $this->getParameter('max_upload_size')
  152.                                 ])
  153.                             );
  154.                     }
  155.     
  156.                     $ticket = new CoreEntites\Ticket();
  157.                     $loggedUser $this->get('security.token_storage')->getToken()->getUser();
  158.                     
  159.                     if(!empty($loggedUser) && $loggedUser != 'anon.') {
  160.                         
  161.                         $form $this->createForm(TicketForm::class, $ticket, [
  162.                             'container' => $container,
  163.                             'entity_manager' => $em,
  164.                         ]);
  165.                         $email $loggedUser->getEmail();
  166.                         try {
  167.                             $name $loggedUser->getFirstName() . ' ' $loggedUser->getLastName();
  168.                         } catch(\Exception $e) {
  169.                             $name explode(' 'strstr($email'@'true));
  170.                         }
  171.                     } else {
  172.                         $form $this->createForm(TicketForm::class, $ticket, [
  173.                             'container' => $container,
  174.                             'entity_manager' => $em,
  175.                         ]);
  176.                         $email $request->request->get('from');
  177.                         $name explode(' '$request->request->get('name'));
  178.                     }
  179.     
  180.                     $website $em->getRepository(CoreEntites\Website::class)->findOneByCode('knowledgebase');
  181.                     if(!empty($email) && $this->ticketService->isEmailBlocked($email$website)) {
  182.                         $request->getSession()->getFlashBag()->set('warning'$this->translator->trans('Warning ! Cannot create ticket, given email is blocked by admin.'));
  183.                         return $this->redirect($this->generateUrl('helpdesk_customer_create_ticket'));
  184.                     }
  185.     
  186.                     if($request->request->all())
  187.                         $form->submit($request->request->all());
  188.     
  189.                     if ($form->isValid() && !count($formErrors) && !$error) {
  190.                         $data = array(
  191.                             'from' => $email//email$request->getSession()->getFlashBag()->set('success', $this->translator->trans('Success ! Ticket has been created successfully.'));
  192.                             'subject' => $request->request->get('subject'),
  193.                             // @TODO: We need to filter js (XSS) instead of html
  194.                             'reply' => str_replace(['&lt;script&gt;''&lt;/script&gt;'], ''htmlspecialchars($request->request->get('reply'))),
  195.                             'firstName' => $name[0],
  196.                             'lastName' => isset($name[1]) ? $name[1] : '',
  197.                             'role' => 4,
  198.                             'active' => true
  199.                         );
  200.     
  201.                         $em $this->getDoctrine()->getManager();
  202.                         $data['type'] = $em->getRepository(CoreEntites\TicketType::class)->find($request->request->get('type'));
  203.     
  204.                         if(!is_object($data['customer'] = $this->container->get('security.token_storage')->getToken()->getUser()) == "anon.") {
  205.                             $supportRole $em->getRepository(CoreEntites\SupportRole::class)->findOneByCode("ROLE_CUSTOMER");
  206.     
  207.                             $customerEmail $params['email'] = $request->request->get('from');
  208.                             $customer $em->getRepository(CoreEntites\User::class)->findOneBy(array('email' => $customerEmail));
  209.                             $params['flag'] = (!$customer) ? 0;
  210.     
  211.                             $data['firstName'] = current($nameDetails explode(' '$request->request->get('name')));
  212.                             $data['fullname'] = $request->request->get('name');
  213.                             $data['lastName'] = ($data['firstName'] != end($nameDetails)) ? end($nameDetails) : " ";
  214.                             $data['from'] = $customerEmail;
  215.                             $data['role'] = 4;
  216.                             $data['customer'] = $this->userService->createUserInstance($customerEmail$data['fullname'], $supportRole$extras = ["active" => true]);
  217.                         } else {
  218.                             $userDetail $em->getRepository(CoreEntites\User::class)->find($data['customer']->getId());
  219.                             $data['email'] = $customerEmail $data['customer']->getEmail();
  220.                             $nameCollection = [$userDetail->getFirstName(), $userDetail->getLastName()];
  221.                             $name implode(' '$nameCollection);
  222.                             $data['fullname'] = $name;
  223.                         }
  224.                         $data['user'] = $data['customer'];
  225.                         $data['subject'] = $request->request->get('subject');
  226.                         $data['source'] = 'website';
  227.                         $data['threadType'] = 'create';
  228.                         $data['message'] = $data['reply'];
  229.                         $data['createdBy'] = 'customer';
  230.                         $data['attachments'] = $request->files->get('attachments');
  231.     
  232.                         if(!empty($request->server->get("HTTP_CF_CONNECTING_IP") )) {
  233.                             $data['ipAddress'] = $request->server->get("HTTP_CF_CONNECTING_IP");
  234.                             if(!empty($request->server->get("HTTP_CF_IPCOUNTRY"))) {
  235.                                 $data['ipAddress'] .= '(' $request->server->get("HTTP_CF_IPCOUNTRY") . ')';
  236.                             }
  237.                         }
  238.     
  239.                         $thread $this->ticketService->createTicketBase($data);
  240.                         
  241.                         if (!empty($thread)) {
  242.                             $ticket $thread->getTicket();
  243.                             if($request->request->get('customFields') || $request->files->get('customFields')) {
  244.                                 $this->ticketService->addTicketCustomFields($thread$request->request->get('customFields'), $request->files->get('customFields'));                        
  245.                             }
  246.                             $this->addFlash('success'$this->translator->trans('Success ! Ticket has been created successfully.'));
  247.                         } else {
  248.                             $this->addFlash('warning'$this->translator->trans('Warning ! Can not create ticket, invalid details.'));
  249.                         }
  250.                         // Trigger ticket created event
  251.                         $event = new GenericEvent(CoreWorkflowEvents\Ticket\Create::getId(), [
  252.                             'entity' => $thread->getTicket(),
  253.                         ]);
  254.     
  255.                         $this->eventDispatcher->dispatch($event'uvdesk.automation.workflow.execute');
  256.     
  257.                         if(null != $this->getUser()) {
  258.                             return $this->redirect($this->generateUrl('helpdesk_customer_ticket_collection'));
  259.                         } else {
  260.                             return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  261.                         }
  262.                         
  263.                     } else {
  264.                         $errors $this->getFormErrors($form);
  265.                         $errors array_merge($errors$formErrors);
  266.                     }
  267.                 } else {
  268.                     $this->addFlash(
  269.                         'warning',
  270.                         $this->translator->trans("Warning ! Post size can not exceed 25MB")
  271.                     );
  272.                 }
  273.     
  274.                 if(isset($errors) && count($errors)) {
  275.                     $this->addFlash('warning'key($errors) . ': ' reset($errors));
  276.                 }
  277.             }
  278.         }
  279.         $breadcrumbs = [
  280.             [
  281.                 'label' => $this->translator->trans('Support Center'),
  282.                 'url' => $this->generateUrl('helpdesk_knowledgebase')
  283.             ],
  284.             [
  285.                 'label' => $this->translator->trans("Create Ticket Request"),
  286.                 'url' => '#'
  287.             ],
  288.         ];
  289.         return $this->render('@UVDeskSupportCenter/Knowledgebase/ticket.html.twig',
  290.             array(
  291.                 'formErrors' => $formErrors,
  292.                 'errors' => json_encode($errors),
  293.                 'customFieldsValues' => $request->request->get('customFields'),
  294.                 'breadcrumbs' => $breadcrumbs,
  295.                 'post' => $post
  296.             )
  297.         );
  298.     }
  299.     public function ticketList(Request $request)
  300.     {
  301.         $em $this->getDoctrine()->getManager();
  302.         $ticketRepo $em->getRepository(CoreEntites\Ticket::class);
  303.         $currentUser $this->get('security.token_storage')->getToken()->getUser();
  304.         if(!$currentUser || $currentUser == "anon.") {
  305.             //throw error
  306.         }
  307.         
  308.         $tickets $ticketRepo->getAllCustomerTickets($currentUser);
  309.         
  310.         return $this->render('@UVDeskSupportCenter/Knowledgebase/ticketList.html.twig', array(
  311.             'ticketList' => $tickets,
  312.         ));
  313.     }
  314.     public function saveReply(int $idRequest $request)
  315.     {
  316.         $this->isWebsiteActive();
  317.         $data $request->request->all();
  318.         $ticket $this->getDoctrine()->getRepository(CoreEntites\Ticket::class)->find($id);
  319.         $user $this->userService->getSessionUser();
  320.         // process only if access for the resource.
  321.         if (empty($ticket) || ( (!empty($user)) && $user->getId() != $ticket->getCustomer()->getId()) ) {
  322.             if(!$this->isCollaborator($ticket$user)) {
  323.                 throw new \Exception('Access Denied'403);
  324.             }
  325.         }
  326.         if($_POST) {
  327.             if(str_replace(' ','',str_replace('&nbsp;','',trim(strip_tags($data['message'], '<img>')))) != "") {
  328.                 if(!$ticket)
  329.                     $this->noResultFound();
  330.                 $data['ticket'] = $ticket;
  331.                 $data['user'] = $this->userService->getCurrentUser();
  332.                 // Checking if reply is from collaborator end
  333.                 $isTicketCollaborator $ticket->getCollaborators() ? $ticket->getCollaborators()->toArray() : [];
  334.                 $isCollaborator false;
  335.                 foreach ($isTicketCollaborator as $value) {
  336.                     if($value->getId() == $data['user']->getId()){
  337.                         $isCollaborator true;
  338.                     }
  339.                 }
  340.                 // @TODO: Refactor -> Why are we filtering only these two characters?
  341.                 $data['message'] = str_replace(['&lt;script&gt;''&lt;/script&gt;'], ''htmlspecialchars($data['message']));
  342.                 $userDetail $this->userService->getCustomerPartialDetailById($data['user']->getId());
  343.                 $data['fullname'] = $userDetail['name'];
  344.                 $data['source'] = 'website';
  345.                 $data['createdBy'] = $isCollaborator 'collaborator' 'customer';
  346.                 $data['attachments'] = $request->files->get('attachments');
  347.                 $thread $this->ticketService->createThread($ticket$data);
  348.                 $em $this->getDoctrine()->getManager();
  349.                 $status $em->getRepository(CoreEntites\TicketStatus::class)->findOneByCode($data['status']);
  350.                 if($status) {
  351.                     $flag 0;
  352.                     if($ticket->getStatus() != $status) {
  353.                         $flag 1;
  354.                     }
  355.                     $ticket->setStatus($status);
  356.                     $em->persist($ticket);
  357.                     $em->flush();
  358.                 }
  359.                 if ($thread->getcreatedBy() == 'customer') {
  360.                     $event = new GenericEvent(CoreWorkflowEvents\Ticket\CustomerReply::getId(), [
  361.                         'entity' =>  $ticket,
  362.                         'thread' =>  $thread
  363.                     ]);
  364.                 } else {
  365.                     $event = new GenericEvent(CoreWorkflowEvents\Ticket\CollaboratorReply::getId(), [
  366.                         'entity' =>  $ticket,
  367.                         'thread' =>  $thread
  368.                     ]);
  369.                 }
  370.                 $this->eventDispatcher->dispatch($event'uvdesk.automation.workflow.execute');
  371.                 $this->addFlash('success'$this->translator->trans('Success ! Reply added successfully.'));
  372.             } else {
  373.                 $this->addFlash('warning'$this->translator->trans('Warning ! Reply field can not be blank.'));
  374.             }
  375.         } else {
  376.             $this->addFlash('warning'$this->translator->trans('Warning ! Post size can not exceed 25MB'));
  377.         }
  378.         return $this->redirect($this->generateUrl('helpdesk_customer_ticket',array(
  379.             'id' => $ticket->getId()
  380.         )));
  381.     }
  382.     public function tickets(Request $request)
  383.     {
  384.         $this->isWebsiteActive();
  385.         // List Announcement if any
  386.         $announcements =  $this->getDoctrine()->getRepository(SupportEntites\Announcement::class)->findBy(['isActive' => 1]);
  387.         $groupAnnouncement = [];
  388.         foreach($announcements as $announcement) {
  389.             $announcementGroupId $announcement->getGroup();
  390.             $isTicketExist =  $this->getDoctrine()->getRepository(CoreEntites\Ticket::class)->findBy(['supportGroup' => $announcementGroupId'customer' => $this->userService->getCurrentUser()]);
  391.             if (!empty($isTicketExist)) {
  392.                 $groupAnnouncement[] = $announcement;
  393.             }
  394.         }
  395.         return $this->render('@UVDeskSupportCenter/Knowledgebase/ticketList.html.twig',
  396.             array(
  397.                 'searchDisable' => true,
  398.                 'groupAnnouncement' => $groupAnnouncement
  399.             )
  400.         );
  401.     }
  402.     /**
  403.      * ticketListXhrAction "Filter and sort ticket collection on ajax request"
  404.      * @param Object $request "HTTP Request object"
  405.      * @return JSON "JSON response"
  406.      */
  407.     public function ticketListXhr(Request $requestContainerInterface $container)
  408.     {
  409.         $this->isWebsiteActive();
  410.         $json = array();
  411.         if($request->isXmlHttpRequest()) {
  412.             $repository $this->getDoctrine()->getRepository(CoreEntites\Ticket::class);
  413.     
  414.             $json $repository->getAllCustomerTickets($request->query$container);
  415.         }
  416.         $response = new Response(json_encode($json));
  417.         $response->headers->set('Content-Type''application/json');
  418.         return $response;
  419.     }
  420.     /**
  421.      * threadListXhrAction "Filter and sort user collection on ajx request"
  422.      * @param Object $request "HTTP Request object"
  423.      * @return JSON "JSON response"
  424.      */
  425.     public function threadListXhr(Request $requestContainerInterface $container)
  426.     {
  427.         $this->isWebsiteActive();
  428.         $json = array();
  429.         if($request->isXmlHttpRequest()) {
  430.             $ticket $this->getDoctrine()->getRepository(CoreEntites\Ticket::class)->find($request->attributes->get('id'));
  431.             // $this->denyAccessUnlessGranted('FRONT_VIEW', $ticket);
  432.             $repository $this->getDoctrine()->getRepository(CoreEntites\Thread::class);
  433.             $json $repository->getAllCustomerThreads($request->attributes->get('id'),$request->query$container);
  434.         }
  435.         $response = new Response(json_encode($json));
  436.         $response->headers->set('Content-Type''application/json');
  437.         return $response;
  438.     }
  439.     public function ticketView($idRequest $request)
  440.     {
  441.         $this->isWebsiteActive();
  442.         $entityManager $this->getDoctrine()->getManager();
  443.         $user $this->userService->getSessionUser();
  444.         $ticket $entityManager->getRepository(CoreEntites\Ticket::class)->findOneBy(['id' => $id]);
  445.         $isConfirmColl false;
  446.         if ($ticket == null && empty($ticket)) {
  447.             throw new NotFoundHttpException('Page Not Found!');
  448.         }
  449.         if (!empty($ticket) && ( (!empty($user)) && $user->getId() != $ticket->getCustomer()->getId()) ) {
  450.             if($this->isCollaborator($ticket$user)) {
  451.                 $isConfirmColl true;
  452.             }
  453.             if ($isConfirmColl != true) {
  454.                 throw new \Exception('Access Denied'403);
  455.             } 
  456.         }
  457.         if (!empty($user) && $user->getId() == $ticket->getCustomer()->getId()) {
  458.             $ticket->setIsCustomerViewed(1);
  459.             $entityManager->persist($ticket);
  460.             $entityManager->flush();
  461.         }
  462.         $checkTicket $entityManager->getRepository(CoreEntites\Ticket::class)->isTicketCollaborator($ticket$user->getEmail());
  463.         
  464.         $twigResponse = [
  465.             'ticket' => $ticket,
  466.             'searchDisable' => true,
  467.             'initialThread' => $this->ticketService->getTicketInitialThreadDetails($ticket),
  468.             'localizedCreateAtTime' => $this->userService->getLocalizedFormattedTime($ticket->getCreatedAt(), $user),
  469.             'isCollaborator' => $checkTicket,
  470.         ];
  471.         return $this->render('@UVDeskSupportCenter/Knowledgebase/ticketView.html.twig'$twigResponse);
  472.     }
  473.     // Check if user is collaborator for the ticket
  474.     public function isCollaborator($ticket$user) {
  475.         $isCollaborator false;
  476.         if(!empty($ticket->getCollaborators()->toArray())) {
  477.             foreach($ticket->getCollaborators()->toArray() as $collaborator) {
  478.                 if($collaborator->getId() == $user->getId()) {
  479.                     $isCollaborator true;
  480.                 }
  481.             }
  482.         }
  483.         return $isCollaborator;
  484.     }
  485.     // Ticket rating
  486.     public function rateTicket(Request $request) {
  487.         $this->isWebsiteActive();
  488.         $json = array();
  489.         $em $this->getDoctrine()->getManager();
  490.         $data json_decode($request->getContent(), true);
  491.         $id $data['id'];
  492.         $count intval($data['rating']);
  493.         
  494.         if($count || $count 6) {
  495.             $ticket $em->getRepository(CoreEntites\Ticket::class)->find($id);
  496.             $customer $this->userService->getCurrentUser();
  497.             $rating $em->getRepository(CoreEntites\TicketRating::class)->findOneBy(array('ticket' => $id,'customer'=>$customer->getId()));
  498.             if($rating) {
  499.                 $rating->setcreatedAt(new \DateTime);
  500.                 $rating->setStars($count);
  501.                 $em->persist($rating);
  502.                 $em->flush();
  503.             } else {
  504.                 $rating = new CoreEntites\TicketRating();
  505.                 $rating->setStars($count);
  506.                 $rating->setCustomer($customer);
  507.                 $rating->setTicket($ticket);
  508.                 $em->persist($rating);
  509.                 $em->flush();
  510.             }
  511.             $json['alertClass'] = 'success';
  512.             $json['alertMessage'] = $this->translator->trans('Success ! Rating has been successfully added.');
  513.         } else {
  514.             $json['alertClass'] = 'danger';
  515.             $json['alertMessage'] = $this->translator->trans('Warning ! Invalid rating.');
  516.         }
  517.         $response = new Response(json_encode($json));
  518.         $response->headers->set('Content-Type''application/json');
  519.         return $response;
  520.     }
  521.     public function downloadAttachmentZip(Request $request)
  522.     {
  523.         $threadId $request->attributes->get('threadId');
  524.         $attachmentRepository $this->getDoctrine()->getManager()->getRepository(CoreEntites\Attachment::class);
  525.         $threadRepository $this->getDoctrine()->getManager()->getRepository(CoreEntites\Thread::class);
  526.         $thread $threadRepository->findOneById($threadId);
  527.         $attachment $attachmentRepository->findByThread($threadId);
  528.         if (!$attachment) {
  529.             $this->noResultFound();
  530.         }
  531.         $ticket $thread->getTicket();
  532.         $user $this->userService->getSessionUser();
  533.         
  534.         // process only if access for the resource.
  535.         if (empty($ticket) || ( (!empty($user)) && $user->getId() != $ticket->getCustomer()->getId()) ) {
  536.             if(!$this->isCollaborator($ticket$user)) {
  537.                 throw new \Exception('Access Denied'403);
  538.             }
  539.         }
  540.         $zipname 'attachments/' .$threadId.'.zip';
  541.         $zip = new \ZipArchive;
  542.         $zip->open($zipname, \ZipArchive::CREATE);
  543.         if(count($attachment)){
  544.             foreach ($attachment as $attach) {
  545.                 $zip->addFile(substr($attach->getPath(), 1)); 
  546.             }
  547.         }
  548.         $zip->close();
  549.         $response = new Response();
  550.         $response->setStatusCode(200);
  551.         $response->headers->set('Content-type''application/zip');
  552.         $response->headers->set('Content-Disposition''attachment; filename=' $threadId '.zip');
  553.         $response->sendHeaders();
  554.         $response->setContent(readfile($zipname));
  555.         return $response;
  556.     }
  557.     public function downloadAttachment(Request $request)
  558.     {
  559.         $attachmendId $request->attributes->get('attachmendId');
  560.         $attachmentRepository $this->getDoctrine()->getManager()->getRepository(CoreEntites\Attachment::class);
  561.         $attachment $attachmentRepository->findOneById($attachmendId);
  562.         $baseurl $request->getScheme() . '://' $request->getHttpHost() . $request->getBasePath();
  563.         if (!$attachment) {
  564.             $this->noResultFound();
  565.         }
  566.         $ticket $attachment->getThread()->getTicket();
  567.         $user $this->userService->getSessionUser();
  568.         
  569.         // process only if access for the resource.
  570.         if (empty($ticket) || ( (!empty($user)) && $user->getId() != $ticket->getCustomer()->getId()) ) {
  571.             if(!$this->isCollaborator($ticket$user)) {
  572.                 throw new \Exception('Access Denied'403);
  573.             }
  574.         }
  575.         $path $this->kernel->getProjectDir() . "/public/"$attachment->getPath();
  576.         $response = new Response();
  577.         $response->setStatusCode(200);
  578.         
  579.         $response->headers->set('Content-type'$attachment->getContentType());
  580.         $response->headers->set('Content-Disposition''attachment; filename='$attachment->getName());
  581.         $response->headers->set('Content-Length'$attachment->getSize());
  582.         $response->sendHeaders();
  583.         $response->setContent(readfile($path));
  584.         
  585.         return $response;
  586.     }
  587.     
  588.     public function ticketCollaboratorXhr(Request $request)
  589.     {
  590.         $json = array();
  591.         $content json_decode($request->getContent(), true);
  592.         $em $this->getDoctrine()->getManager();
  593.         $ticket $em->getRepository(CoreEntites\Ticket::class)->find($content['ticketId']);
  594.         $user $this->userService->getSessionUser();
  595.         
  596.         // process only if access for the resource.
  597.         if (empty($ticket) || ( (!empty($user)) && $user->getId() != $ticket->getCustomer()->getId()) ) {
  598.             if(!$this->isCollaborator($ticket$user)) {
  599.                 throw new \Exception('Access Denied'403);
  600.             }
  601.         }
  602.         
  603.         if ($request->getMethod() == "POST") {
  604.             if ($content['email'] == $ticket->getCustomer()->getEmail()) {
  605.                 $json['alertClass'] = 'danger';
  606.                 $json['alertMessage'] = $this->translator->trans('Error ! Can not add customer as a collaborator.');
  607.             } else {
  608.                 $data = array(
  609.                     'from' => $content['email'],
  610.                     'firstName' => ($firstName ucfirst(current(explode('@'$content['email'])))),
  611.                     'lastName' => ' ',
  612.                     'role' => 4,
  613.                 );
  614.                 $supportRole $em->getRepository(CoreEntites\SupportRole::class)->findOneByCode('ROLE_CUSTOMER');
  615.                 $collaborator $this->userService->createUserInstance($data['from'], $data['firstName'], $supportRole$extras = ["active" => true]);
  616.                 
  617.                 $checkTicket $em->getRepository(CoreEntites\Ticket::class)->isTicketCollaborator($ticket,$content['email']);
  618.                 
  619.                 if (!$checkTicket) {
  620.                     $ticket->addCollaborator($collaborator);
  621.                     $em->persist($ticket);
  622.                     $em->flush();
  623.                     $ticket->lastCollaborator $collaborator;
  624.                     $collaborator $em->getRepository(CoreEntites\User::class)->find($collaborator->getId());
  625.                     
  626.                     $event = new GenericEvent(CoreWorkflowEvents\Ticket\Collaborator::getId(), [
  627.                         'entity' => $ticket,
  628.                     ]);
  629.                     $this->eventDispatcher->dispatch($event'uvdesk.automation.workflow.execute');
  630.                    
  631.                     $json['collaborator'] =  $this->userService->getCustomerPartialDetailById($collaborator->getId());
  632.                     $json['alertClass'] = 'success';
  633.                     $json['alertMessage'] = $this->translator->trans('Success ! Collaborator added successfully.');
  634.                 } else {
  635.                     $json['alertClass'] = 'danger';
  636.                     $json['alertMessage'] = $this->translator->trans('Error ! Collaborator is already added.');
  637.                 }
  638.             }
  639.         } elseif ($request->getMethod() == "DELETE") {
  640.             $collaborator $em->getRepository(CoreEntites\User::class)->findOneBy(array('id' => $request->attributes->get('id')));
  641.             
  642.             if ($collaborator) {
  643.                 $ticket->removeCollaborator($collaborator);
  644.                 $em->persist($ticket);
  645.                 $em->flush();
  646.                 $json['alertClass'] = 'success';
  647.                 $json['alertMessage'] = $this->translator->trans('Success ! Collaborator removed successfully.');
  648.             } else {
  649.                 $json['alertClass'] = 'danger';
  650.                 $json['alertMessage'] = $this->translator->trans('Error ! Invalid Collaborator.');
  651.             }
  652.         }
  653.         $response = new Response(json_encode($json));
  654.         $response->headers->set('Content-Type''application/json');
  655.         return $response;
  656.     }
  657. }