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

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