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

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