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

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