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

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