vendor/uvdesk/core-framework/Services/TicketService.php line 67

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\CoreFrameworkBundle\Services;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Doctrine\ORM\Query;
  5. use Symfony\Component\DependencyInjection\ContainerInterface;
  6. use Symfony\Component\EventDispatcher\GenericEvent;
  7. use Symfony\Component\Filesystem\Filesystem;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpFoundation\Response;
  10. use Symfony\Component\HttpFoundation\RequestStack;
  11. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  12. use Symfony\Component\Yaml\Yaml;
  13. use UVDesk\CommunityPackages\UVDesk\FormComponent\Entity;
  14. use UVDesk\CommunityPackages\UVDesk\FormComponent\Entity as CommunityPackageEntities;
  15. use Webkul\UVDesk\AutomationBundle\Entity\PreparedResponses;
  16. use Webkul\UVDesk\CoreFrameworkBundle\Entity\User;
  17. use Webkul\UVDesk\CoreFrameworkBundle\Entity\AgentActivity;
  18. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Ticket;
  19. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Thread;
  20. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Tag;
  21. use Webkul\UVDesk\CoreFrameworkBundle\Entity\TicketType;
  22. use Webkul\UVDesk\CoreFrameworkBundle\Entity\TicketStatus;
  23. use Webkul\UVDesk\CoreFrameworkBundle\Entity\TicketPriority;
  24. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportRole;
  25. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Website;
  26. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportGroup;
  27. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportTeam;
  28. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportLabel;
  29. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SavedReplies;
  30. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Attachment;
  31. use Webkul\UVDesk\CoreFrameworkBundle\Utils\TokenGenerator;
  32. use Webkul\UVDesk\CoreFrameworkBundle\Workflow\Events as CoreWorkflowEvents;
  33. use Webkul\UVDesk\CoreFrameworkBundle\Services\FileUploadService;
  34. use Webkul\UVDesk\CoreFrameworkBundle\Services\UserService;
  35. use Webkul\UVDesk\MailboxBundle\Utils\Mailbox\Mailbox;
  36. use Webkul\UVDesk\MailboxBundle\Utils\MailboxConfiguration;
  37. use Webkul\UVDesk\MailboxBundle\Utils\IMAP\Configuration as ImapConfiguration;
  38. use Webkul\UVDesk\SupportCenterBundle\Entity\Article;
  39. use Webkul\UVDesk\SupportCenterBundle\Entity\KnowledgebaseWebsite;
  40. use Webkul\UVDesk\MailboxBundle\Services\MailboxService;
  41. class TicketService
  42. {
  43.     const PATH_TO_CONFIG '/config/packages/uvdesk_mailbox.yaml';
  44.     protected $container;
  45.     protected $requestStack;
  46.     protected $entityManager;
  47.     protected $fileUploadService;
  48.     protected $userService;
  49.     
  50.     public function __construct(
  51.         ContainerInterface $container
  52.         RequestStack $requestStack
  53.         EntityManagerInterface $entityManager
  54.         FileUploadService $fileUploadService,
  55.         UserService $userService
  56.         MailboxService $mailboxService
  57.     ) {
  58.         $this->container $container;
  59.         $this->requestStack $requestStack;
  60.         $this->entityManager $entityManager;
  61.         $this->fileUploadService $fileUploadService;
  62.         $this->userService $userService;
  63.         $this->mailboxService $mailboxService;
  64.     }
  65.     public function getPathToConfigurationFile()
  66.     {
  67.         return $this->container->get('kernel')->getProjectDir() . self::PATH_TO_CONFIG;
  68.     }
  69.     public function generateRandomEmailReferenceId()
  70.     {
  71.         $emailDomain null;
  72.         $mailbox $this->mailboxService->parseMailboxConfigurations()->getDefaultMailbox();
  73.         if (!empty($mailbox)) {
  74.             $smtpConfiguration $mailbox->getSmtpConfiguration();
  75.             if (!empty($smtpConfiguration)) {
  76.                 $emailDomain substr($smtpConfiguration->getUsername(), strpos($smtpConfiguration->getUsername(), '@'));
  77.             }
  78.         }
  79.         if (!empty($emailDomain)) {
  80.             return sprintf("<%s%s>"TokenGenerator::generateToken(20'0123456789abcdefghijklmnopqrstuvwxyz'), $emailDomain);
  81.         }
  82.         return null;
  83.     }
  84.     // @TODO: Refactor this out of this service. Use UserService::getSessionUser() instead.
  85.     public function getUser()
  86.     {
  87.         return $this->container->get('user.service')->getCurrentUser();
  88.     }
  89.     public function getDefaultType()
  90.     {
  91.         $typeCode $this->container->getParameter('uvdesk.default.ticket.type');
  92.         $ticketType $this->entityManager->getRepository(TicketType::class)->findOneByCode($typeCode);
  93.         return !empty($ticketType) ? $ticketType null;
  94.     }
  95.     public function getDefaultStatus()
  96.     {
  97.         $statusCode $this->container->getParameter('uvdesk.default.ticket.status');
  98.         $ticketStatus $this->entityManager->getRepository(TicketStatus::class)->findOneByCode($statusCode);
  99.         return !empty($ticketStatus) ? $ticketStatus null;
  100.     }
  101.     public function getDefaultPriority()
  102.     {
  103.         $priorityCode $this->container->getParameter('uvdesk.default.ticket.priority');
  104.         $ticketPriority $this->entityManager->getRepository(TicketPriority::class)->findOneByCode($priorityCode);
  105.         return !empty($ticketPriority) ? $ticketPriority null;
  106.     }
  107.     public function appendTwigSnippet($snippet '')
  108.     {
  109.         switch ($snippet) {
  110.             case 'createMemberTicket':
  111.                 return $this->getMemberCreateTicketSnippet();
  112.                 break;
  113.             default:
  114.                 break;
  115.         }
  116.         return '';
  117.     }
  118.     public function getMemberCreateTicketSnippet()
  119.     {   
  120.         $twigTemplatingEngine $this->container->get('twig');
  121.         $ticketTypeCollection $this->entityManager->getRepository(TicketType::class)->findByIsActive(true);
  122.         
  123.         try {
  124.             if ($this->userService->isfileExists('apps/uvdesk/custom-fields')) {
  125.                 $headerCustomFields $this->container->get('uvdesk_package_custom_fields.service')->getCustomFieldsArray('user');
  126.             } else if ($this->userService->isfileExists('apps/uvdesk/form-component')) {
  127.                 $headerCustomFields $this->container->get('uvdesk_package_form_component.service')->getCustomFieldsArray('user');
  128.             }
  129.         } catch (\Exception $e) {
  130.             // @TODO: Log execption message
  131.         }
  132.         return $twigTemplatingEngine->render('@UVDeskCoreFramework/Snippets/createMemberTicket.html.twig', [
  133.             'ticketTypeCollection' => $ticketTypeCollection,
  134.             'headerCustomFields' => $headerCustomFields ?? null,
  135.         ]);
  136.     }
  137.     public function getCustomerCreateTicketCustomFieldSnippet()
  138.     {
  139.         try {
  140.             if ($this->userService->isfileExists('apps/uvdesk/custom-fields')) {
  141.                 $customFields $this->container->get('uvdesk_package_custom_fields.service')->getCustomFieldsArray('customer');
  142.             } else if ($this->userService->isfileExists('apps/uvdesk/form-component')) {
  143.                 $customFields $this->container->get('uvdesk_package_form_component.service')->getCustomFieldsArray('customer');
  144.             }
  145.         } catch (\Exception $e) {
  146.             // @TODO: Log execption message
  147.         }
  148.         return $customFields ?? null;
  149.     }
  150.     public function createTicket(array $params = [])
  151.     {
  152.         $thread $this->entityManager->getRepository(Thread::class)->findOneByMessageId($params['messageId']);
  153.         if (empty($thread)) {
  154.             $user $this->entityManager->getRepository(User::class)->findOneByEmail($params['from']);
  155.             if (empty($user) || null == $user->getCustomerInstance()) {
  156.                 $role $this->entityManager->getRepository(SupportRole::class)->findOneByCode($params['role']);
  157.                 if (empty($role)) {
  158.                     throw new \Exception("The requested role '" $params['role'] . "' does not exist.");
  159.                 }
  160.                 
  161.                 // Create User Instance
  162.                 $user $this->container->get('user.service')->createUserInstance($params['from'], $params['name'], $role, [
  163.                     'source' => strtolower($params['source']),
  164.                     'active' => true,
  165.                 ]);
  166.             }
  167.             $params['role'] = 4;
  168.             $params['mailboxEmail'] = current($params['replyTo']); 
  169.             $params['customer'] = $params['user'] = $user;
  170.             return $this->createTicketBase($params);
  171.         }
  172.         return;
  173.     }
  174.     public function createTicketBase(array $ticketData = [])
  175.     {
  176.         if ('email' == $ticketData['source']) {
  177.             try {
  178.                 if (array_key_exists('UVDeskMailboxBundle'$this->container->getParameter('kernel.bundles'))) {
  179.                     $mailbox $this->mailboxService->getMailboxByEmail($ticketData['mailboxEmail']);
  180.                 }
  181.             } catch (\Exception $e) {
  182.                 // No mailbox found for this email. Skip ticket creation.
  183.                 return;
  184.             }
  185.         }
  186.         // Set Defaults
  187.         $ticketType = !empty($ticketData['type']) ? $ticketData['type'] : $this->getDefaultType();
  188.         $ticketStatus = !empty($ticketData['status']) ? $ticketData['status'] : $this->getDefaultStatus();
  189.         $ticketPriority = !empty($ticketData['priority']) ? $ticketData['priority'] : $this->getDefaultPriority();
  190.         if ('email' == $ticketData['source']) {
  191.             $ticketMessageId = !empty($ticketData['messageId']) ? $ticketData['messageId'] : null;
  192.         } else {
  193.             $ticketMessageId $this->generateRandomEmailReferenceId();
  194.         }
  195.         $ticketData['type'] = $ticketType;
  196.         $ticketData['status'] = $ticketStatus;
  197.         $ticketData['priority'] = $ticketPriority;
  198.         $ticketData['messageId'] = $ticketMessageId;
  199.         $ticketData['isTrashed'] = false;
  200.         $ticket = new Ticket();
  201.         foreach ($ticketData as $property => $value) {
  202.             $callable 'set' ucwords($property);
  203.             if (method_exists($ticket$callable)) {
  204.                 $ticket->$callable($value);
  205.             }
  206.         }
  207.         $this->entityManager->persist($ticket);
  208.         $this->entityManager->flush();
  209.         return $this->createThread($ticket$ticketData);
  210.     }
  211.     
  212.     public function createThread(Ticket $ticket, array $threadData)
  213.     {
  214.         $threadData['isLocked'] = 0;
  215.       
  216.         if ('forward' === $threadData['threadType']) {
  217.             $threadData['replyTo'] = $threadData['to'];
  218.         }
  219.         $collaboratorEmails array_merge(!empty($threadData['cccol']) ? $threadData['cccol'] : [], !empty($threadData['cc']) ? $threadData['cc'] : []);
  220.         
  221.         if (!empty($collaboratorEmails)) {
  222.             $threadData['cc'] = $collaboratorEmails;
  223.         }
  224.    
  225.         $thread = new Thread();
  226.         $thread->setTicket($ticket);
  227.         $thread->setCreatedAt(new \DateTime());
  228.         $thread->setUpdatedAt(new \DateTime());
  229.         if ($threadData['threadType'] != "note") {
  230.             foreach ($threadData as $property => $value) {
  231.                 if (!empty($value)) {
  232.                     $callable 'set' ucwords($property);
  233.                     if (method_exists($thread$callable)) {
  234.                         $thread->$callable($value);
  235.                     }
  236.                 }
  237.             }
  238.         } else {
  239.             $this->setTicketNotePlaceholderValue($thread$threadData$ticket);
  240.         }
  241.         // Update ticket reference ids is thread message id is defined
  242.         if (null != $thread->getMessageId() && false === strpos($ticket->getReferenceIds(), $thread->getMessageId())) {
  243.             $updatedReferenceIds $ticket->getReferenceIds() . ' ' $thread->getMessageId();            
  244.             $ticket->setReferenceIds($updatedReferenceIds);
  245.             $this->entityManager->persist($ticket);
  246.         }
  247.         if ('reply' === $threadData['threadType']) {
  248.             if ('agent' === $threadData['createdBy']) {
  249.                 // Ticket has been updated by support agents, mark as agent replied | customer view pending
  250.                 $ticket->setIsCustomerViewed(false);
  251.                 $ticket->setIsReplied(true);
  252.                 $customerName $ticket->getCustomer()->getFirstName().' '.$ticket->getCustomer()->getLastName();
  253.                 $agentActivity = new AgentActivity();
  254.                 $agentActivity->setThreadType('reply');
  255.                 $agentActivity->setTicket($ticket);
  256.                 $agentActivity->setAgent($thread->getUser());
  257.                 $agentActivity->setCustomerName($customerName);
  258.                 $agentActivity->setAgentName('agent');
  259.                 $agentActivity->setCreatedAt(new \DateTime());
  260.                 $this->entityManager->persist($agentActivity);
  261.             } else {
  262.                 // Ticket has been updated by customer, mark as agent view | reply pending
  263.                 $ticket->setIsAgentViewed(false);
  264.                 $ticket->setIsReplied(false);
  265.             }
  266.             $this->entityManager->persist($ticket);
  267.         } else if ('create' === $threadData['threadType']) {
  268.             $ticket->setIsReplied(false);
  269.             $this->entityManager->persist($ticket);
  270.             $customerName $ticket->getCustomer()->getFirstName().' '.$ticket->getCustomer()->getLastName();
  271.             $agentActivity = new AgentActivity();
  272.             $agentActivity->setThreadType('create');
  273.             $agentActivity->setTicket($ticket);
  274.             $agentActivity->setAgent($thread->getUser());
  275.             $agentActivity->setCustomerName($customerName );
  276.             $agentActivity->setAgentName('agent');
  277.             $agentActivity->setCreatedAt(new \DateTime());
  278.             $this->entityManager->persist($agentActivity);
  279.         }
  280.         
  281.         $ticket->currentThread $this->entityManager->getRepository(Thread::class)->getTicketCurrentThread($ticket);
  282.         
  283.         $this->entityManager->persist($thread);
  284.         $this->entityManager->flush();
  285.         
  286.         $ticket->createdThread $thread;
  287.         // Uploading Attachments
  288.         if (!empty($threadData['attachments'])) {
  289.             if ('email' == $threadData['source']) {
  290.                 $this->saveThreadEmailAttachments($thread$threadData['attachments']);
  291.             } else if (!empty($threadData['attachments'])) {
  292.                 $this->saveThreadAttachment($thread$threadData['attachments']);
  293.             }
  294.         }
  295.         return $thread;
  296.     }
  297.     public function setTicketNotePlaceholderValue($thread$threadData$ticket)
  298.     {
  299.         if (!empty($threadData)) {
  300.             foreach ($threadData as $property => $value) {
  301.                 if (!empty($value)) {
  302.                     $callable 'set' ucwords($property);
  303.                     if (method_exists($thread$callable)) {
  304.                         if($callable != "setMessage") {
  305.                             $thread->$callable($value);
  306.                         } else {
  307.                             $notesPlaceholders $this->getNotePlaceholderValues($ticket'customer');
  308.                             $content $value;
  309.                             foreach ($notesPlaceholders as $key => $val) {
  310.                                 if(strpos($value"{%$key%}") !== false){
  311.                                     $content strtr($value, ["{%$key%}" => $val"{% $key %}" => $val]);
  312.                                 }
  313.                             }
  314.                             
  315.                             $content stripslashes($content);
  316.                             $thread->$callable($content);
  317.                         }
  318.                     }
  319.                 }
  320.             }
  321.         }
  322.     }
  323.     public function saveThreadAttachment($thread, array $attachments)
  324.     {
  325.         $prefix 'threads/' $thread->getId();
  326.         $uploadManager $this->container->get('uvdesk.core.file_system.service')->getUploadManager();
  327.         foreach ($attachments as $attachment) {
  328.             $uploadedFileAttributes $uploadManager->uploadFile($attachment$prefix);
  329.             if (!empty($uploadedFileAttributes['path'])) {
  330.                 ($threadAttachment = new Attachment())
  331.                     ->setThread($thread)
  332.                     ->setName($uploadedFileAttributes['name'])
  333.                     ->setPath($uploadedFileAttributes['path'])
  334.                     ->setSize($uploadedFileAttributes['size'])
  335.                     ->setContentType($uploadedFileAttributes['content-type']);
  336.                 
  337.                 $this->entityManager->persist($threadAttachment);
  338.             }
  339.         }
  340.         $this->entityManager->flush();
  341.     }
  342.     public function saveThreadEmailAttachments($thread, array $attachments)
  343.     {
  344.         $prefix 'threads/' $thread->getId();
  345.         $uploadManager $this->container->get('uvdesk.core.file_system.service')->getUploadManager();
  346.         
  347.         // Upload thread attachments
  348.         foreach ($attachments as $attachment) {
  349.             $uploadedFileAttributes $uploadManager->uploadEmailAttachment($attachment$prefix);
  350.             
  351.             if (!empty($uploadedFileAttributes['path'])) {
  352.                 ($threadAttachment = new Attachment())
  353.                     ->setThread($thread)
  354.                     ->setName($uploadedFileAttributes['name'])
  355.                     ->setPath($uploadedFileAttributes['path'])
  356.                     ->setSize($uploadedFileAttributes['size'])
  357.                     ->setContentType($uploadedFileAttributes['content-type']);
  358.                 
  359.                 $this->entityManager->persist($threadAttachment);
  360.             }
  361.         }
  362.         $this->entityManager->flush();
  363.     }
  364.     public function getTypes()
  365.     {
  366.         static $types;
  367.         if (null !== $types)
  368.             return $types;
  369.         $qb $this->entityManager->createQueryBuilder();
  370.         $qb->select('tp.id','tp.code As name')->from(TicketType::class, 'tp')
  371.                 ->andwhere('tp.isActive = 1')
  372.                 ->orderBy('tp.code''ASC');
  373.         return $types $qb->getQuery()->getArrayResult();
  374.     }
  375.     public function getStatus()
  376.     {
  377.         static $statuses;
  378.         if (null !== $statuses)
  379.             return $statuses;
  380.         $qb $this->entityManager->createQueryBuilder();
  381.         $qb->select('ts')->from(TicketStatus::class, 'ts');
  382.         // $qb->orderBy('ts.sortOrder', Criteria::ASC);
  383.         return $statuses $qb->getQuery()->getArrayResult();
  384.     }
  385.     public function getTicketTotalThreads($ticketId)
  386.     {
  387.         $qb $this->entityManager->createQueryBuilder();
  388.         $qb->select('COUNT(th.id) as threadCount')->from(Ticket::class, 't')
  389.             ->leftJoin('t.threads''th')
  390.             ->andWhere('t.id = :ticketId')
  391.             ->andWhere('th.threadType = :threadType')
  392.             ->setParameter('threadType','reply')
  393.             ->setParameter('ticketId'$ticketId);
  394.         $qb $this->entityManager->createQueryBuilder();
  395.         $qb->select('COUNT(t.id) as threadCount')->from(Thread::class, 't')
  396.             ->andWhere('t.ticket = :ticketId')
  397.             ->andWhere('t.threadType = :threadType')
  398.             ->setParameter('threadType','reply')
  399.             ->setParameter('ticketId'$ticketId);
  400.         return $qb->getQuery()->getSingleScalarResult();
  401.     }
  402.     public function getTicketTags($request null)
  403.     {
  404.         $qb $this->entityManager->createQueryBuilder();
  405.         $qb->select('tg')->from(Tag::class, 'tg');
  406.         if($request) {
  407.             $qb->andwhere("tg.name LIKE :tagName");
  408.             $qb->setParameter('tagName''%'.urldecode($request->query->get('query')).'%');
  409.             $qb->andwhere("tg.id NOT IN (:ids)");
  410.             $qb->setParameter('ids'explode(',',urldecode($request->query->get('not'))));
  411.         }
  412.         return $qb->getQuery()->getArrayResult();
  413.     }
  414.     
  415.     public function paginateMembersTicketCollection(Request $request)
  416.     {
  417.         $params $request->query->all();
  418.         $activeUser $this->container->get('user.service')->getSessionUser();
  419.         $activeUserTimeZone $this->entityManager->getRepository(Website::class)->findOneBy(['code' => 'Knowledgebase']);
  420.         $agentTimeZone = !empty($activeUser->getTimezone()) ? $activeUser->getTimezone() : $activeUserTimeZone->getTimezone();
  421.         $agentTimeFormat = !empty($activeUser->getTimeformat()) ? $activeUser->getTimeformat() : $activeUserTimeZone->getTimeformat();
  422.         $ticketRepository $this->entityManager->getRepository(Ticket::class);
  423.         $website $this->entityManager->getRepository(Website::class)->findOneBy(['code' => 'helpdesk']);
  424.         $timeZone $website->getTimezone();
  425.         $timeFormat $website->getTimeformat();
  426.         $supportGroupReference $this->entityManager->getRepository(User::class)->getUserSupportGroupReferences($activeUser);
  427.         $supportTeamReference  $this->entityManager->getRepository(User::class)->getUserSupportTeamReferences($activeUser);
  428.         // Get base query
  429.         $baseQuery $ticketRepository->prepareBaseTicketQuery($activeUser$supportGroupReference$supportTeamReference$params);
  430.         $ticketTabs $ticketRepository->getTicketTabDetails($activeUser$supportGroupReference$supportTeamReference$params);
  431.         // Apply Pagination
  432.         $pageNumber = !empty($params['page']) ? (int) $params['page'] : 1;
  433.         $itemsLimit = !empty($params['limit']) ? (int) $params['limit'] : $ticketRepository::DEFAULT_PAGINATION_LIMIT;
  434.         if (isset($params['repliesLess']) || isset($params['repliesMore'])) {
  435.             $paginationOptions = ['wrap-queries' => true];
  436.             $paginationQuery $baseQuery->getQuery()
  437.                 ->setHydrationMode(Query::HYDRATE_ARRAY);
  438.         } else {
  439.             $paginationOptions = ['distinct' => true];
  440.             $paginationQuery $baseQuery->getQuery()
  441.                 ->setHydrationMode(Query::HYDRATE_ARRAY)
  442.                 ->setHint('knp_paginator.count', isset($params['status']) ? $ticketTabs[$params['status']] : $ticketTabs[1]);
  443.         }
  444.         $pagination $this->container->get('knp_paginator')->paginate($paginationQuery$pageNumber$itemsLimit$paginationOptions);
  445.         // Process Pagination Response
  446.         $ticketCollection = [];
  447.         $paginationParams $pagination->getParams();
  448.         $paginationData $pagination->getPaginationData();
  449.         $paginationParams['page'] = 'replacePage';
  450.         $paginationData['url'] = '#' $this->container->get('uvdesk.service')->buildPaginationQuery($paginationParams);
  451.         // $container->get('default.service')->buildSessionUrl('ticket',$queryParameters);
  452.         $ticketThreadCountQueryTemplate $this->entityManager->createQueryBuilder()
  453.             ->select('COUNT(thread.id) as threadCount')
  454.             ->from(Ticket::class, 'ticket')
  455.             ->leftJoin('ticket.threads''thread')
  456.             ->where('ticket.id = :ticketId')
  457.             ->andWhere('thread.threadType = :threadType')->setParameter('threadType''reply');
  458.         
  459.         foreach ($pagination->getItems() as $ticketDetails) {
  460.             $ticket array_shift($ticketDetails);
  461.             $ticketThreadCountQuery = clone $ticketThreadCountQueryTemplate;
  462.             $ticketThreadCountQuery->setParameter('ticketId'$ticket['id']);
  463.             $totalTicketReplies = (int) $ticketThreadCountQuery->getQuery()->getSingleScalarResult();
  464.             $ticketHasAttachments false;
  465.             $dbTime $ticket['createdAt'];
  466.             
  467.             $formattedTime$this->fomatTimeByPreference($dbTime,$timeZone,$timeFormat,$agentTimeZone,$agentTimeFormat);
  468.             $currentDateTime  = new \DateTime('now');
  469.             if($this->getLastReply($ticket['id'])) {
  470.                 $lastRepliedTime 
  471.                 $this->time2string($currentDateTime->getTimeStamp() - $this->getLastReply($ticket['id'])['createdAt']->getTimeStamp());
  472.             } else {
  473.                 $lastRepliedTime 
  474.                 $this->time2string($currentDateTime->getTimeStamp() - $ticket['createdAt']->getTimeStamp());
  475.             }
  476.             $ticketResponse = [
  477.                 'id' => $ticket['id'],
  478.                 'subject' => $ticket['subject'],
  479.                 'isStarred' => $ticket['isStarred'],
  480.                 'isAgentView' => $ticket['isAgentViewed'],
  481.                 'isTrashed' => $ticket['isTrashed'],
  482.                 'source' => $ticket['source'],
  483.                 'group' => $ticketDetails['groupName'],
  484.                 'team' => $ticketDetails['teamName'],
  485.                 'priority' => $ticket['priority'],
  486.                 'type' => $ticketDetails['typeName'],
  487.                 'timestamp' => $formattedTime['dateTimeZone'],
  488.                 'formatedCreatedAt' => $formattedTime['dateTimeZone']->format($formattedTime['timeFormatString']),
  489.                 'totalThreads' => $totalTicketReplies,
  490.                 'agent' => null,
  491.                 'customer' => null,
  492.                 'hasAttachments' => $ticketHasAttachments,
  493.                 'lastReplyTime' => $lastRepliedTime
  494.             ];
  495.            
  496.             if (!empty($ticketDetails['agentId'])) {
  497.                 $ticketResponse['agent'] = [
  498.                     'id' => $ticketDetails['agentId'],
  499.                     'name' => $ticketDetails['agentName'],
  500.                     'smallThumbnail' => $ticketDetails['smallThumbnail'],
  501.                 ];
  502.             }
  503.             if (!empty($ticketDetails['customerId'])) {
  504.                 $ticketResponse['customer'] = [
  505.                     'id' => $ticketDetails['customerId'],
  506.                     'name' => $ticketDetails['customerName'],
  507.                     'email' => $ticketDetails['customerEmail'],
  508.                     'smallThumbnail' => $ticketDetails['customersmallThumbnail'],
  509.                 ];
  510.             }
  511.             array_push($ticketCollection$ticketResponse);
  512.         }
  513.          
  514.         return [
  515.             'tickets' => $ticketCollection,
  516.             'pagination' => $paginationData,
  517.             'tabs' => $ticketTabs,
  518.             'labels' => [
  519.                 'predefind' => $this->getPredefindLabelDetails($activeUser$supportGroupReference$supportTeamReference$params),
  520.                 'custom' => $this->getCustomLabelDetails($this->container),
  521.             ],
  522.           
  523.         ];
  524.     }
  525.     // Convert Timestamp to day/hour/min
  526.     Public function time2string($time) {
  527.         $d floor($time/86400);
  528.         $_d = ($d 10 '0' '').$d;
  529.         $h floor(($time-$d*86400)/3600);
  530.         $_h = ($h 10 '0' '').$h;
  531.         $m floor(($time-($d*86400+$h*3600))/60);
  532.         $_m = ($m 10 '0' '').$m;
  533.         $s $time-($d*86400+$h*3600+$m*60);
  534.         $_s = ($s 10 '0' '').$s;
  535.         $time_str "0 minutes";
  536.         if($_d != 00)
  537.             $time_str $_d." ".'days';
  538.         elseif($_h != 00)
  539.             $time_str $_h." ".'hours';
  540.         elseif($_m != 00)
  541.             $time_str $_m." ".'minutes';
  542.         return $time_str." "."ago";
  543.     }
  544.     public function getPredefindLabelDetails(User $currentUser, array $supportGroupIds = [], array $supportTeamIds = [], array $params = [])
  545.     {
  546.         $data = array();
  547.         $queryBuilder $this->entityManager->createQueryBuilder();
  548.         $ticketRepository $this->entityManager->getRepository(Ticket::class);
  549.         $queryBuilder->select('COUNT(DISTINCT ticket.id) as ticketCount')->from(Ticket::class, 'ticket');
  550.             
  551.         // // applyFilter according to permission
  552.         $queryBuilder->where('ticket.isTrashed != 1');
  553.         $userInstance $currentUser->getAgentInstance();
  554.         if (!empty($userInstance) &&  'ROLE_AGENT' == $userInstance->getSupportRole()->getCode() 
  555.         && $userInstance->getTicketAccesslevel() != 1) {
  556.             $supportGroupIds implode(','$supportGroupIds);
  557.             $supportTeamIds implode(','$supportTeamIds);
  558.             if ($userInstance->getTicketAccesslevel() == 4) {
  559.                 $queryBuilder->andwhere('ticket.agent = ' $currentUser->getId());
  560.             } elseif ($userInstance->getTicketAccesslevel() == 2) {
  561.                 $query '';
  562.                 if ($supportGroupIds){
  563.                     $query .= ' OR supportGroup.id IN('.$supportGroupIds.') ';
  564.                 }
  565.                 if ($supportTeamIds) {
  566.                     $query .= ' OR supportTeam.id IN('.$supportTeamIds.') ';
  567.                 }
  568.                 $queryBuilder->leftJoin('ticket.supportGroup''supportGroup')
  569.                             ->leftJoin('ticket.supportTeam''supportTeam')
  570.                             ->andwhere('( ticket.agent = ' $currentUser->getId().$query.')');
  571.                     
  572.             } elseif ($userInstance->getTicketAccesslevel() == 3) {
  573.                 $query '';
  574.                 if ($supportTeamIds) {
  575.                     $query .= ' OR supportTeam.id IN('.$supportTeamIds.') ';
  576.                 }
  577.                 $queryBuilder->leftJoin('ticket.supportGroup''supportGroup')
  578.                             ->leftJoin('ticket.supportTeam''supportTeam')
  579.                             ->andwhere('( ticket.agent = ' $currentUser->getId().$query')');
  580.             }
  581.         }
  582.         // for all tickets count
  583.         $data['all'] = $queryBuilder->getQuery()->getSingleScalarResult();
  584.         // for new tickets count
  585.         $newQb = clone $queryBuilder;
  586.         $newQb->andwhere('ticket.isNew = 1');
  587.         $data['new'] = $newQb->getQuery()->getSingleScalarResult();
  588.         // for unassigned tickets count
  589.         $unassignedQb = clone $queryBuilder;
  590.         $unassignedQb->andwhere("ticket.agent is NULL");
  591.         $data['unassigned'] = $unassignedQb->getQuery()->getSingleScalarResult();
  592.         // for unanswered ticket count
  593.         $unansweredQb = clone $queryBuilder;
  594.         $unansweredQb->andwhere('ticket.isReplied = 0');
  595.         $data['notreplied'] = $unansweredQb->getQuery()->getSingleScalarResult();
  596.         // for my tickets count
  597.         $mineQb = clone $queryBuilder;
  598.         $mineQb->andWhere("ticket.agent = :agentId")
  599.                 ->setParameter('agentId'$currentUser->getId());
  600.         $data['mine'] = $mineQb->getQuery()->getSingleScalarResult();
  601.         // for starred tickets count
  602.         $starredQb = clone $queryBuilder;
  603.         $starredQb->andwhere('ticket.isStarred = 1');
  604.         $data['starred'] = $starredQb->getQuery()->getSingleScalarResult();
  605.         // for trashed tickets count
  606.         $trashedQb = clone $queryBuilder;
  607.         $trashedQb->where('ticket.isTrashed = 1');
  608.         if ($currentUser->getRoles()[0] != 'ROLE_SUPER_ADMIN' && $userInstance->getTicketAccesslevel() != 1) {
  609.             $trashedQb->andwhere('ticket.agent = ' $currentUser->getId());
  610.         }
  611.         $data['trashed'] = $trashedQb->getQuery()->getSingleScalarResult();
  612.         return $data;
  613.     }
  614.     
  615.     public function paginateMembersTicketThreadCollection(Ticket $ticketRequest $request)
  616.     {
  617.         $params $request->query->all();
  618.         $entityManager $this->entityManager;
  619.         $activeUser $this->container->get('user.service')->getSessionUser();
  620.         $activeUserTimeZone $this->entityManager->getRepository(Website::class)->findOneBy(['code' => 'Knowledgebase']);
  621.         $agentTimeZone = !empty($activeUser->getTimezone()) ? $activeUser->getTimezone() : $activeUserTimeZone->getTimezone();
  622.         $agentTimeFormat = !empty($activeUser->getTimeformat()) ? $activeUser->getTimeformat() : $activeUserTimeZone->getTimeformat();
  623.         
  624.         $threadRepository $entityManager->getRepository(Thread::class);
  625.         $uvdeskFileSystemService $this->container->get('uvdesk.core.file_system.service');
  626.         // Get base query
  627.         $enableLockedThreads $this->container->get('user.service')->isAccessAuthorized('ROLE_AGENT_MANAGE_LOCK_AND_UNLOCK_THREAD');
  628.         $baseQuery $threadRepository->prepareBasePaginationRecentThreadsQuery($ticket$params$enableLockedThreads);
  629.         
  630.         // Apply Pagination
  631.         $paginationItemsQuery = clone $baseQuery;
  632.         $totalPaginationItems $paginationItemsQuery->select('COUNT(DISTINCT thread.id)')->getQuery()->getSingleScalarResult();
  633.         
  634.         $pageNumber = !empty($params['page']) ? (int) $params['page'] : 1;
  635.         $itemsLimit = !empty($params['limit']) ? (int) $params['limit'] : $threadRepository::DEFAULT_PAGINATION_LIMIT;
  636.         
  637.         $paginationOptions = ['distinct' => true];
  638.         $paginationQuery $baseQuery->getQuery()->setHydrationMode(Query::HYDRATE_ARRAY)->setHint('knp_paginator.count', (int) $totalPaginationItems);
  639.         $pagination $this->container->get('knp_paginator')->paginate($paginationQuery$pageNumber$itemsLimit$paginationOptions);
  640.         // Process Pagination Response
  641.         $threadCollection = [];
  642.         $paginationParams $pagination->getParams();
  643.         $paginationData $pagination->getPaginationData();
  644.         $website $this->entityManager->getRepository(Website::class)->findOneBy(['code' => 'helpdesk']);
  645.         $timeZone $website->getTimezone();
  646.         $timeFormat $website->getTimeformat();
  647.         if (!empty($params['threadRequestedId'])) {
  648.             $requestedThreadCollection $baseQuery
  649.                 ->andWhere('thread.id >= :threadRequestedId')->setParameter('threadRequestedId', (int) $params['threadRequestedId'])
  650.                 ->getQuery()->getArrayResult();
  651.             
  652.             $totalRequestedThreads count($requestedThreadCollection);
  653.             $paginationData['current'] = ceil($totalRequestedThreads $threadRepository::DEFAULT_PAGINATION_LIMIT);
  654.             if ($paginationData['current'] > 1) {
  655.                 $paginationData['firstItemNumber'] = 1;
  656.                 $paginationData['lastItemNumber'] = $totalRequestedThreads;
  657.                 $paginationData['next'] = ceil(($totalRequestedThreads 1) / $threadRepository::DEFAULT_PAGINATION_LIMIT);
  658.             }
  659.         }
  660.         $paginationParams['page'] = 'replacePage';
  661.         $paginationData['url'] = '#' $this->container->get('uvdesk.service')->buildPaginationQuery($paginationParams);
  662.         foreach ($pagination->getItems() as $threadDetails) {
  663.             $dbTime $threadDetails['createdAt'];
  664.             $formattedTime $this->fomatTimeByPreference($dbTime,$timeZone,$timeFormat,$agentTimeZone,$agentTimeFormat);
  665.             $threadResponse = [
  666.                 'id' => $threadDetails['id'],
  667.                 'user' => null,
  668.                 'fullname' => null,
  669.                 'reply' => html_entity_decode($threadDetails['message']),
  670.                 'source' => $threadDetails['source'],
  671.                 'threadType' => $threadDetails['threadType'],
  672.                 'userType' => $threadDetails['createdBy'],
  673.                 'timestamp' => $formattedTime['dateTimeZone'],
  674.                 'formatedCreatedAt' => $formattedTime['dateTimeZone']->format($formattedTime['timeFormatString']),
  675.                 'bookmark' => $threadDetails['isBookmarked'],
  676.                 'isLocked' => $threadDetails['isLocked'],
  677.                 'replyTo' => $threadDetails['replyTo'],
  678.                 'cc' => $threadDetails['cc'],
  679.                 'bcc' => $threadDetails['bcc'],
  680.                 'attachments' => $threadDetails['attachments'],
  681.             ];
  682.   
  683.             if (!empty($threadDetails['user'])) {
  684.                 $threadResponse['fullname'] = trim($threadDetails['user']['firstName'] . ' ' $threadDetails['user']['lastName']);
  685.                 $threadResponse['user'] = [
  686.                     'id' => $threadDetails['user']['id'],
  687.                     'smallThumbnail' => $threadDetails['user']['userInstance'][0]['profileImagePath'],
  688.                     'name' => $threadResponse['fullname'],
  689.                 ];
  690.             }
  691.             if (!empty($threadResponse['attachments'])) {
  692.                 $threadResponse['attachments'] = array_map(function ($attachment) use ($entityManager$uvdeskFileSystemService) {
  693.                     $attachmentReferenceObject $entityManager->getReference(Attachment::class, $attachment['id']);
  694.                     return $uvdeskFileSystemService->getFileTypeAssociations($attachmentReferenceObject);
  695.                 }, $threadResponse['attachments']);
  696.             }
  697.             array_push($threadCollection$threadResponse);
  698.         }
  699.         return [
  700.             'threads' => $threadCollection,
  701.             'pagination' => $paginationData,
  702.         ];
  703.     }
  704.     public function massXhrUpdate(Request $request)
  705.     {
  706.         $params $request->request->get('data');
  707.         foreach ($params['ids'] as $ticketId) {
  708.             $ticket $this->entityManager->getRepository(Ticket::class)->find($ticketId);
  709.             if (false == $this->isTicketAccessGranted($ticket)) {
  710.                 throw new \Exception('Access Denied'403);
  711.             }
  712.             
  713.             if (empty($ticket)) {
  714.                 continue;
  715.             }
  716.             switch ($params['actionType']) {
  717.                 case 'trashed':
  718.                     if (false == $ticket->getIsTrashed()) {
  719.                         $ticket->setIsTrashed(true);
  720.                         
  721.                         $this->entityManager->persist($ticket);
  722.                     }
  723.                     // Trigger ticket delete event
  724.                     $event = new GenericEvent(CoreWorkflowEvents\Ticket\Delete::getId(), [
  725.                         'entity' => $ticket,
  726.                     ]);
  727.                     $this->container->get('event_dispatcher')->dispatch($event'uvdesk.automation.workflow.execute');
  728.                     break;
  729.                 case 'delete':
  730.                     $threads $ticket->getThreads();
  731.                     $fileService = new Filesystem();
  732.                     if (count($threads) > 0) {
  733.                         foreach($threads as $thread) {
  734.                             if (!empty($thread)) {
  735.                                 $fileService->remove($this->container->getParameter('kernel.project_dir').'/public/assets/threads/'.$thread->getId());
  736.                             }
  737.                         }
  738.                     }
  739.                     $this->entityManager->remove($ticket);
  740.                     
  741.                     break;
  742.                 case 'restored':
  743.                     if (true == $ticket->getIsTrashed()) {
  744.                         $ticket->setIsTrashed(false);
  745.                         $this->entityManager->persist($ticket);
  746.                     }
  747.                     break;
  748.                 case 'agent':
  749.                     if ($ticket->getAgent() == null || $ticket->getAgent() && $ticket->getAgent()->getId() != $params['targetId']) {
  750.                         $agent $this->entityManager->getRepository(User::class)->find($params['targetId']);
  751.                         $ticket->setAgent($agent);
  752.     
  753.                         $this->entityManager->persist($ticket);
  754.     
  755.                         // Trigger Agent Assign event
  756.                         $event = new GenericEvent(CoreWorkflowEvents\Ticket\Agent::getId(), [
  757.                             'entity' => $ticket,
  758.                         ]);
  759.     
  760.                         $this->container->get('event_dispatcher')->dispatch($event'uvdesk.automation.workflow.execute');
  761.                     }
  762.                     break;
  763.                 case 'status':
  764.                     if ($ticket->getStatus() == null || $ticket->getStatus() && $ticket->getStatus()->getId() != $params['targetId']) {
  765.                         $status $this->entityManager->getRepository(TicketStatus::class)->findOneById($params['targetId']);
  766.                         $ticket->setStatus($status);
  767.                         $this->entityManager->persist($ticket);
  768.                         // Trigger ticket status event
  769.                         $event = new GenericEvent(CoreWorkflowEvents\Ticket\Status::getId(), [
  770.                             'entity' => $ticket,
  771.                         ]);
  772.                         
  773.                         $this->container->get('event_dispatcher')->dispatch($event'uvdesk.automation.workflow.execute');
  774.                     }
  775.                     
  776.                     break;
  777.                 case 'type':
  778.                     if ($ticket->getType() == null || $ticket->getType() && $ticket->getType()->getId() != $params['targetId']) {
  779.                         $type $this->entityManager->getRepository(TicketType::class)->findOneById($params['targetId']);
  780.                         $ticket->setType($type);
  781.     
  782.                         $this->entityManager->persist($ticket);
  783.     
  784.                         // Trigger ticket type event
  785.                         $event = new GenericEvent(CoreWorkflowEvents\Ticket\Type::getId(), [
  786.                             'entity' => $ticket,
  787.                         ]);
  788.     
  789.                         $this->container->get('event_dispatcher')->dispatch($event'uvdesk.automation.workflow.execute');
  790.                     }
  791.                     break;
  792.                 case 'group':
  793.                     if ($ticket->getSupportGroup() == null || $ticket->getSupportGroup() && $ticket->getSupportGroup()->getId() != $params['targetId']) {
  794.                         $group $this->entityManager->getRepository(SupportGroup::class)->find($params['targetId']);
  795.                         $ticket->setSupportGroup($group);
  796.     
  797.                         $this->entityManager->persist($ticket);
  798.     
  799.                         // Trigger Support group event
  800.                         $event = new GenericEvent(CoreWorkflowEvents\Ticket\Group::getId(), [
  801.                             'entity' => $ticket,
  802.                         ]);
  803.     
  804.                         $this->container->get('event_dispatcher')->dispatch($event'uvdesk.automation.workflow.execute');
  805.                     }
  806.                     break;
  807.                 case 'team':
  808.                     if ($ticket->getSupportTeam() == null || $ticket->getSupportTeam() && $ticket->getSupportTeam()->getId() != $params['targetId']){
  809.                         $team $this->entityManager->getRepository(SupportTeam::class)->find($params['targetId']);
  810.                         $ticket->setSupportTeam($team);
  811.                         
  812.                         $this->entityManager->persist($ticket);
  813.         
  814.                         // Trigger team event
  815.                         $event = new GenericEvent(CoreWorkflowEvents\Ticket\Team::getId(), [
  816.                             'entity' => $ticket,
  817.                         ]);
  818.         
  819.                         $this->container->get('event_dispatcher')->dispatch($event'uvdesk.automation.workflow.execute');
  820.                     }
  821.                     break;
  822.                 case 'priority':
  823.                     if ($ticket->getPriority() == null || $ticket->getPriority() && $ticket->getPriority()->getId() != $params['targetId']) {
  824.                         
  825.                         $priority $this->entityManager->getRepository(TicketPriority::class)->find($params['targetId']);
  826.                         $ticket->setPriority($priority);
  827.     
  828.                         $this->entityManager->persist($ticket);
  829.     
  830.                         // Trigger ticket Priority event
  831.                         $event = new GenericEvent(CoreWorkflowEvents\Ticket\Priority::getId(), [
  832.                             'entity' => $ticket,
  833.                         ]);
  834.     
  835.                         $this->container->get('event_dispatcher')->dispatch($event'uvdesk.automation.workflow.execute');
  836.                     }
  837.                     break;
  838.                 case 'label':
  839.                     $label $this->entityManager->getRepository(SupportLabel::class)->find($params['targetId']);
  840.                     
  841.                     if ($label && !$this->entityManager->getRepository(Ticket::class)->isLabelAlreadyAdded($ticket$label)) {
  842.                         $ticket->addSupportLabel($label);
  843.                     }
  844.                     
  845.                     $this->entityManager->persist($ticket);
  846.                     break;
  847.                 default:
  848.                     break;
  849.             }
  850.         } 
  851.         $this->entityManager->flush();
  852.         return [
  853.             'alertClass' => 'success',
  854.             'alertMessage' => $this->trans('Tickets have been updated successfully'),
  855.         ];
  856.     }
  857.     
  858.     public function getNotePlaceholderValues($ticket$type "customer")
  859.     {
  860.         $variables = array();
  861.         $variables['ticket.id'] = $ticket->getId();
  862.         $variables['ticket.subject'] = $ticket->getSubject();
  863.         $variables['ticket.status'] = $ticket->getStatus()->getCode();
  864.         $variables['ticket.priority'] = $ticket->getPriority()->getCode();
  865.         if($ticket->getSupportGroup())
  866.             $variables['ticket.group'] = $ticket->getSupportGroup()->getName();
  867.         else
  868.             $variables['ticket.group'] = '';
  869.         $variables['ticket.team'] = ($ticket->getSupportTeam() ? $ticket->getSupportTeam()->getName() : '');
  870.         $customer $this->container->get('user.service')->getCustomerPartialDetailById($ticket->getCustomer()->getId());
  871.         $variables['ticket.customerName'] = $customer['name'];
  872.         $userService $this->container->get('user.service');
  873.       
  874.         $variables['ticket.agentName'] = '';
  875.         $variables['ticket.agentEmail'] = '';
  876.         if ($ticket->getAgent()) {
  877.             $agent $this->container->get('user.service')->getAgentDetailById($ticket->getAgent()->getId());
  878.             if($agent) {
  879.                 $variables['ticket.agentName'] = $agent['name'];
  880.                 $variables['ticket.agentEmail'] = $agent['email'];
  881.             }
  882.         }
  883.         $router $this->container->get('router');
  884.         if ($type == 'customer') {
  885.             $ticketListURL $router->generate('helpdesk_member_ticket_collection', [
  886.                 'id' => $ticket->getId(),
  887.             ], UrlGeneratorInterface::ABSOLUTE_URL);
  888.         } else {
  889.             $ticketListURL $router->generate('helpdesk_customer_ticket_collection', [
  890.                 'id' => $ticket->getId(),
  891.             ], UrlGeneratorInterface::ABSOLUTE_URL);
  892.         }
  893.         $variables['ticket.link'] = sprintf("<a href='%s'>#%s</a>"$ticketListURL$ticket->getId());
  894.         return $variables;
  895.     }
  896.     public function paginateMembersTicketTypeCollection(Request $request)
  897.     {
  898.         // Get base query
  899.         $params $request->query->all();
  900.         $ticketRepository $this->entityManager->getRepository(Ticket::class);
  901.         $paginationQuery $ticketRepository->prepareBasePaginationTicketTypesQuery($params);
  902.         // Apply Pagination
  903.         $paginationOptions = ['distinct' => true];
  904.         $pageNumber = !empty($params['page']) ? (int) $params['page'] : 1;
  905.         $itemsLimit = !empty($params['limit']) ? (int) $params['limit'] : $ticketRepository::DEFAULT_PAGINATION_LIMIT;
  906.         $pagination $this->container->get('knp_paginator')->paginate($paginationQuery$pageNumber$itemsLimit$paginationOptions);
  907.         // Process Pagination Response
  908.         $paginationParams $pagination->getParams();
  909.         $paginationData $pagination->getPaginationData();
  910.         $paginationParams['page'] = 'replacePage';
  911.         $paginationData['url'] = '#' $this->container->get('uvdesk.service')->buildPaginationQuery($paginationParams);
  912.         return [
  913.             'types' => array_map(function ($ticketType) {
  914.                 return [
  915.                     'id' => $ticketType->getId(),
  916.                     'code' => strtoupper($ticketType->getCode()),
  917.                     'description' => $ticketType->getDescription(),
  918.                     'isActive' => $ticketType->getIsActive(),
  919.                 ];
  920.             }, $pagination->getItems()),
  921.             'pagination_data' => $paginationData,
  922.         ];
  923.     }
  924.     public function paginateMembersTagCollection(Request $request)
  925.     {
  926.         // Get base query
  927.         $params $request->query->all();
  928.         $ticketRepository $this->entityManager->getRepository(Ticket::class);
  929.         $baseQuery $ticketRepository->prepareBasePaginationTagsQuery($params);
  930.         // Apply Pagination
  931.         $paginationResultsQuery = clone $baseQuery;
  932.         $paginationResultsQuery->select('COUNT(supportTag.id)');
  933.         $paginationQuery $baseQuery->getQuery()->setHydrationMode(Query::HYDRATE_ARRAY)->setHint('knp_paginator.count'count($paginationResultsQuery->getQuery()->getResult()));
  934.         $paginationOptions = ['distinct' => true];
  935.         $pageNumber = !empty($params['page']) ? (int) $params['page'] : 1;
  936.         $itemsLimit = !empty($params['limit']) ? (int) $params['limit'] : $ticketRepository::DEFAULT_PAGINATION_LIMIT;
  937.         $pagination $this->container->get('knp_paginator')->paginate($paginationQuery$pageNumber$itemsLimit$paginationOptions);
  938.         // Process Pagination Response
  939.         $paginationParams $pagination->getParams();
  940.         $paginationData $pagination->getPaginationData();
  941.         $paginationParams['page'] = 'replacePage';
  942.         $paginationData['url'] = '#' $this->container->get('uvdesk.service')->buildPaginationQuery($paginationParams);
  943.         if (in_array('UVDeskSupportCenterBundle'array_keys($this->container->getParameter('kernel.bundles')))) {
  944.             $articleRepository $this->entityManager->getRepository(Article::class);
  945.             return [
  946.                 'tags' => array_map(function ($supportTag) use ($articleRepository) {
  947.                     return [
  948.                         'id' => $supportTag['id'],
  949.                         'name' => $supportTag['name'],
  950.                         'ticketCount' => $supportTag['totalTickets'],
  951.                         'articleCount' => $articleRepository->getTotalArticlesBySupportTag($supportTag['id']),
  952.                     ];
  953.                 }, $pagination->getItems()),
  954.                 'pagination_data' => $paginationData,
  955.             ];
  956.         } else {
  957.             return [
  958.                 'tags' => array_map(function ($supportTag) {
  959.                     return [
  960.                         'id' => $supportTag['id'],
  961.                         'name' => $supportTag['name'],
  962.                         'ticketCount' => $supportTag['totalTickets'],
  963.                     ];
  964.                 }, $pagination->getItems()),
  965.                 'pagination_data' => $paginationData,
  966.             ];
  967.         }
  968.     }
  969.     public function getTicketInitialThreadDetails(Ticket $ticket)
  970.     {
  971.         $initialThread $this->entityManager->getRepository(Thread::class)->findOneBy([
  972.             'ticket' => $ticket,
  973.             'threadType' => 'create',
  974.         ]);
  975.         if (!empty($initialThread)) {
  976.             $author $initialThread->getUser();
  977.             $authorInstance 'agent' == $initialThread->getCreatedBy() ? $author->getAgentInstance() : $author->getCustomerInstance();
  978.         
  979.             $threadDetails = [
  980.                 'id' => $initialThread->getId(),
  981.                 'source' => $initialThread->getSource(),
  982.                 'messageId' => $initialThread->getMessageId(),
  983.                 'threadType' => $initialThread->getThreadType(),
  984.                 'createdBy' => $initialThread->getCreatedBy(),
  985.                 'message' => html_entity_decode($initialThread->getMessage()),
  986.                 'attachments' => $initialThread->getAttachments(),
  987.                 'timestamp' => $initialThread->getCreatedAt()->getTimestamp(),
  988.                 'createdAt' => $initialThread->getCreatedAt()->format('d-m-Y h:ia'),
  989.                 'user' => $authorInstance->getPartialDetails(),
  990.                 'cc' => is_array($initialThread->getCc()) ? implode(', '$initialThread->getCc()) : '',
  991.             ];
  992.             $attachments $threadDetails['attachments']->getValues();
  993.             if (!empty($attachments)) {
  994.                 $uvdeskFileSystemService $this->container->get('uvdesk.core.file_system.service');
  995.                 $threadDetails['attachments'] = array_map(function ($attachment) use ($uvdeskFileSystemService) {
  996.                     return $uvdeskFileSystemService->getFileTypeAssociations($attachment);
  997.                 }, $attachments);
  998.             }
  999.         }
  1000.         return $threadDetails ?? null;
  1001.     }
  1002.     public function getCreateReply($ticketId$firewall 'member')
  1003.     {
  1004.         $qb $this->entityManager->createQueryBuilder();
  1005.         $qb->select("th,a,u.id as userId")->from(Thread::class, 'th')
  1006.                 ->leftJoin('th.ticket','t')
  1007.                 ->leftJoin('th.attachments''a')
  1008.                 ->leftJoin('th.user','u')
  1009.                 ->andWhere('t.id = :ticketId')
  1010.                 ->andWhere('th.threadType = :threadType')
  1011.                 ->setParameter('threadType','create')
  1012.                 ->setParameter('ticketId',$ticketId)
  1013.                 ->orderBy('th.id''DESC')
  1014.                 ->getMaxResults(1);
  1015.         $threadResponse $qb->getQuery()->getArrayResult();
  1016.         if((!empty($threadResponse[0][0]))) {
  1017.             $threadDetails $threadResponse[0][0];
  1018.             $userService $this->container->get('user.service');
  1019.             
  1020.             if ($threadDetails['createdBy'] == 'agent') {
  1021.                 $threadDetails['user'] = $userService->getAgentDetailById($threadResponse[0]['userId']);
  1022.             } else {
  1023.                 $threadDetails['user'] = $userService->getCustomerPartialDetailById($threadResponse[0]['userId']);
  1024.             }
  1025.             
  1026.             $threadDetails['reply'] = html_entity_decode($threadDetails['message']);
  1027.             $threadDetails['formatedCreatedAt'] = $this->timeZoneConverter($threadDetails['createdAt']);    
  1028.             $threadDetails['timestamp'] = $userService->convertToDatetimeTimezoneTimestamp($threadDetails['createdAt']);
  1029.         
  1030.             if (!empty($threadDetails['attachments'])) {
  1031.                 $entityManager $this->entityManager;
  1032.                 $uvdeskFileSystemService $this->container->get('uvdesk.core.file_system.service');
  1033.                 $threadDetails['attachments'] = array_map(function ($attachment) use ($entityManager$uvdeskFileSystemService$firewall) {
  1034.                     $attachmentReferenceObject $entityManager->getReference(Attachment::class, $attachment['id']);
  1035.                     return $uvdeskFileSystemService->getFileTypeAssociations($attachmentReferenceObject$firewall);
  1036.                 }, $threadDetails['attachments']);
  1037.             }
  1038.         }
  1039.         
  1040.         return $threadDetails ?? null;
  1041.     }
  1042.     public function hasAttachments($ticketId) {
  1043.         $qb $this->entityManager->createQueryBuilder();
  1044.         $qb->select("DISTINCT COUNT(a.id) as attachmentCount")->from(Thread::class, 'th')
  1045.                 ->leftJoin('th.ticket','t')
  1046.                 ->leftJoin('th.attachments','a')
  1047.                 ->andWhere('t.id = :ticketId')
  1048.                 ->setParameter('ticketId',$ticketId);
  1049.         return intval($qb->getQuery()->getSingleScalarResult());
  1050.     }
  1051.     public function getAgentDraftReply()
  1052.     {
  1053.         $signature $this->getUser()->getAgentInstance()->getSignature();
  1054.         
  1055.         return str_replace"\n"'<br/>'$signature);
  1056.     }
  1057.     public function trans($text)
  1058.     {
  1059.         return $this->container->get('translator')->trans($text);
  1060.     }
  1061.     public function getAllSources()
  1062.     {
  1063.         $sources = ['email' => 'Email''website' => 'Website'];
  1064.         return $sources;
  1065.     }
  1066.     public function getCustomLabelDetails($container)
  1067.     {
  1068.         $currentUser $container->get('user.service')->getCurrentUser();
  1069.         $qb $this->entityManager->createQueryBuilder();
  1070.         $qb->select('COUNT(DISTINCT t) as ticketCount,sl.id')->from(Ticket::class, 't')
  1071.                 ->leftJoin('t.supportLabels','sl')
  1072.                 ->andwhere('sl.user = :userId')
  1073.                 ->setParameter('userId'$currentUser->getId())
  1074.                 ->groupBy('sl.id');
  1075.         $ticketCountResult $qb->getQuery()->getResult();
  1076.         $data = array();
  1077.         $qb $this->entityManager->createQueryBuilder();
  1078.         $qb->select('sl.id,sl.name,sl.colorCode')->from(SupportLabel::class, 'sl')
  1079.                 ->andwhere('sl.user = :userId')
  1080.                 ->setParameter('userId'$currentUser->getId());
  1081.         $labels $qb->getQuery()->getResult();
  1082.         foreach ($labels as $key => $label) {
  1083.             $labels[$key]['count'] = 0;
  1084.             foreach ($ticketCountResult as $ticketCount) {
  1085.                 if(($label['id'] == $ticketCount['id']))
  1086.                     $labels[$key]['count'] = $ticketCount['ticketCount'] ?: 0;
  1087.             }
  1088.         }
  1089.         return $labels;
  1090.     }
  1091.     public function getLabels($request null)
  1092.     {
  1093.         static $labels;
  1094.         if (null !== $labels)
  1095.             return $labels;
  1096.         $qb $this->entityManager->createQueryBuilder();
  1097.         $qb->select('sl')->from(SupportLabel::class, 'sl')
  1098.             ->andwhere('sl.user = :userId')
  1099.             ->setParameter('userId'$this->getUser()->getId());
  1100.         if($request) {
  1101.             $qb->andwhere("sl.name LIKE :labelName");
  1102.             $qb->setParameter('labelName''%'.urldecode($request->query->get('query')).'%');
  1103.         }
  1104.         return $labels $qb->getQuery()->getArrayResult();
  1105.     }
  1106.     public function getTicketCollaborators($ticketId)
  1107.     {
  1108.         $qb $this->entityManager->createQueryBuilder();
  1109.         $qb->select("DISTINCT c.id, c.email, CONCAT(c.firstName,' ', c.lastName) AS name, userInstance.profileImagePath, userInstance.profileImagePath as smallThumbnail")->from(Ticket::class, 't')
  1110.                 ->leftJoin('t.collaborators''c')
  1111.                 ->leftJoin('c.userInstance''userInstance')
  1112.                 ->andwhere('t.id = :ticketId')
  1113.                 ->andwhere('userInstance.supportRole = :roles')
  1114.                 ->setParameter('ticketId'$ticketId)
  1115.                 ->setParameter('roles'4)
  1116.                 ->orderBy('name','ASC');
  1117.         return $qb->getQuery()->getArrayResult();
  1118.     }
  1119.     public function getTicketTagsById($ticketId)
  1120.     {
  1121.         $qb $this->entityManager->createQueryBuilder();
  1122.         $qb->select('tg')->from(Tag::class, 'tg')
  1123.                 ->leftJoin('tg.tickets' ,'t')
  1124.                 ->andwhere('t.id = :ticketId')
  1125.                 ->setParameter('ticketId'$ticketId);
  1126.         return $qb->getQuery()->getArrayResult();
  1127.     }
  1128.     public function getTicketLabels($ticketId)
  1129.     {
  1130.         $qb $this->entityManager->createQueryBuilder();
  1131.         $qb->select('DISTINCT sl.id,sl.name,sl.colorCode')->from(Ticket::class, 't')
  1132.                 ->leftJoin('t.supportLabels','sl')
  1133.                 ->leftJoin('sl.user','slu')
  1134.                 ->andWhere('slu.id = :userId')
  1135.                 ->andWhere('t.id = :ticketId')
  1136.                 ->setParameter('userId'$this->getUser()->getId())
  1137.                 ->setParameter('ticketId'$ticketId);
  1138.         $result $qb->getQuery()->getResult();
  1139.         
  1140.         return $result $result : [];
  1141.     }
  1142.     public function getUserLabels()
  1143.     {
  1144.         $qb $this->entityManager->createQueryBuilder();
  1145.         $qb->select('sl')->from(SupportLabel::class, 'sl')
  1146.                 ->leftJoin('sl.user','slu')
  1147.                 ->andWhere('slu.id = :userId')
  1148.                 ->setParameter('userId'$this->getUser()->getId());
  1149.         $result $qb->getQuery()->getResult();
  1150.         
  1151.         return $result $result : [];
  1152.     }
  1153.     public function getTicketLabelsAll($ticketId)
  1154.     {
  1155.         $qb $this->entityManager->createQueryBuilder();
  1156.         $qb->select('DISTINCT sl.id,sl.name,sl.colorCode')->from(Ticket::class, 't')
  1157.                 ->leftJoin('t.supportLabels','sl')
  1158.                 ->andWhere('t.id = :ticketId')
  1159.                 ->setParameter('ticketId'$ticketId);
  1160.         $result $qb->getQuery()->getResult();
  1161.         
  1162.         return $result $result : [];
  1163.     }
  1164.     public function getManualWorkflow()
  1165.     {
  1166.         $preparedResponseIds = [];
  1167.         $groupIds = [];
  1168.         $teamIds = []; 
  1169.         $userId $this->container->get('user.service')->getCurrentUser()->getAgentInstance()->getId();
  1170.         $preparedResponseRepo $this->entityManager->getRepository(PreparedResponses::class)->findAll();
  1171.         foreach ($preparedResponseRepo as $pr) {
  1172.             if ($userId == $pr->getUser()->getId()) {
  1173.                 //Save the ids of the saved reply.
  1174.                 array_push($preparedResponseIds, (int)$pr->getId());
  1175.             }
  1176.         }
  1177.         // Get the ids of the Group(s) the current user is associated with.
  1178.         $query "select * from uv_user_support_groups where userInstanceId =".$userId;
  1179.         $connection $this->entityManager->getConnection();
  1180.         $stmt $connection->prepare($query);
  1181.         $stmt->execute();
  1182.         $result $stmt->fetchAll();
  1183.         foreach ($result as $row) {
  1184.             array_push($groupIds$row['supportGroupId']);
  1185.         }
  1186.         // Get all the saved reply's ids that is associated with the user's group(s).
  1187.         $query "select * from uv_prepared_response_support_groups";
  1188.         $stmt $connection->prepare($query);
  1189.         $stmt->execute();
  1190.         $result $stmt->fetchAll();
  1191.         foreach ($result as $row) {
  1192.             if (in_array($row['group_id'], $groupIds)) {
  1193.                 array_push($preparedResponseIds, (int) $row['savedReply_id']);
  1194.             }
  1195.         }
  1196.         // Get the ids of the Team(s) the current user is associated with.
  1197.         $query "select * from uv_user_support_teams";
  1198.         $connection $this->entityManager->getConnection();
  1199.         $stmt $connection->prepare($query);
  1200.         $stmt->execute();
  1201.         $result $stmt->fetchAll();
  1202.         foreach($result as $row) {
  1203.             if ($row['userInstanceId'] == $userId) {
  1204.                 array_push($teamIds$row['supportTeamId']);
  1205.             }
  1206.         }
  1207.         $query "select * from uv_prepared_response_support_teams";
  1208.         $stmt $connection->prepare($query);
  1209.         $stmt->execute();
  1210.         $result $stmt->fetchAll();
  1211.         foreach ($result as $row) {
  1212.             if (in_array($row['subgroup_id'], $teamIds)) {
  1213.                 array_push($preparedResponseIds, (int)$row['savedReply_id']);
  1214.             }
  1215.         }
  1216.         $qb $this->entityManager->createQueryBuilder();
  1217.         $qb->select('DISTINCT mw')
  1218.             ->from(PreparedResponses::class, 'mw')
  1219.             ->where('mw.status = 1')
  1220.             ->andWhere('mw.id IN (:ids)')
  1221.             ->setParameter('ids'$preparedResponseIds);
  1222.         
  1223.         return $qb->getQuery()->getResult();
  1224.     }
  1225.     public function getSavedReplies()
  1226.     {   
  1227.         $savedReplyIds = [];
  1228.         $groupIds = [];
  1229.         $teamIds = []; 
  1230.         $userId $this->container->get('user.service')->getCurrentUser()->getAgentInstance()->getId();
  1231.         $savedReplyRepo $this->entityManager->getRepository(SavedReplies::class)->findAll();
  1232.         foreach ($savedReplyRepo as $sr) {
  1233.             if ($userId == $sr->getUser()->getId()) {
  1234.                 //Save the ids of the saved reply.
  1235.                 array_push($savedReplyIds, (int)$sr->getId());
  1236.             }
  1237.         }
  1238.         // Get the ids of the Group(s) the current user is associated with.
  1239.         $query "select * from uv_user_support_groups where userInstanceId =".$userId;
  1240.         $connection $this->entityManager->getConnection();
  1241.         $stmt $connection->prepare($query);
  1242.         $stmt->execute();
  1243.         $result $stmt->fetchAll();
  1244.         foreach ($result as $row) {
  1245.             array_push($groupIds$row['supportGroupId']);
  1246.         }
  1247.         // Get all the saved reply's ids that is associated with the user's group(s).
  1248.         $query "select * from uv_saved_replies_groups";
  1249.         $stmt $connection->prepare($query);
  1250.         $stmt->execute();
  1251.         $result $stmt->fetchAll();
  1252.         foreach ($result as $row) {
  1253.             if (in_array($row['group_id'], $groupIds)) {
  1254.                 array_push($savedReplyIds, (int) $row['savedReply_id']);
  1255.             }
  1256.         }
  1257.         // Get the ids of the Team(s) the current user is associated with.
  1258.         $query "select * from uv_user_support_teams";
  1259.         $connection $this->entityManager->getConnection();
  1260.         $stmt $connection->prepare($query);
  1261.         $stmt->execute();
  1262.         $result $stmt->fetchAll();
  1263.         foreach($result as $row) {
  1264.             if ($row['userInstanceId'] == $userId) {
  1265.                 array_push($teamIds$row['supportTeamId']);
  1266.             }
  1267.         }
  1268.         $query "select * from uv_saved_replies_teams";
  1269.         $stmt $connection->prepare($query);
  1270.         $stmt->execute();
  1271.         $result $stmt->fetchAll();
  1272.         foreach ($result as $row) {
  1273.             if (in_array($row['subgroup_id'], $teamIds)) {
  1274.                 array_push($savedReplyIds, (int)$row['savedReply_id']);
  1275.             }
  1276.         }
  1277.         $qb $this->entityManager->createQueryBuilder();
  1278.         $qb->select('DISTINCT sr')
  1279.         ->from(SavedReplies::class, 'sr')
  1280.         ->Where('sr.id IN (:ids)')
  1281.         ->setParameter('ids'$savedReplyIds);
  1282.         
  1283.         return $qb->getQuery()->getResult();
  1284.     }
  1285.     public function getPriorities()
  1286.     {
  1287.         static $priorities;
  1288.         if (null !== $priorities)
  1289.             return $priorities;
  1290.         $qb $this->entityManager->createQueryBuilder();
  1291.         $qb->select('tp')->from(TicketPriority::class, 'tp');
  1292.         return $priorities $qb->getQuery()->getArrayResult();
  1293.     }
  1294.     public function getTicketLastThread($ticketId)
  1295.     {
  1296.         $qb $this->entityManager->createQueryBuilder();
  1297.         $qb->select("th")->from(Thread::class, 'th')
  1298.                 ->leftJoin('th.ticket','t')
  1299.                 ->andWhere('t.id = :ticketId')
  1300.                 ->setParameter('ticketId',$ticketId)
  1301.                 ->orderBy('th.id''DESC');
  1302.         return $qb->getQuery()->setMaxResults(1)->getSingleResult();
  1303.     }
  1304.     public function getlastReplyAgentName($ticketId)
  1305.     {
  1306.         $qb $this->entityManager->createQueryBuilder();
  1307.         $qb->select("u.id,CONCAT(u.firstName,' ', u.lastName) AS name,u.firstName")->from(Thread::class, 'th')
  1308.                 ->leftJoin('th.ticket','t')
  1309.                 ->leftJoin('th.user''u')
  1310.                 ->leftJoin('u.userInstance''userInstance')
  1311.                 ->andwhere('userInstance.supportRole != :roles')
  1312.                 ->andWhere('t.id = :ticketId')
  1313.                 ->andWhere('th.threadType = :threadType')
  1314.                 ->setParameter('threadType','reply')
  1315.                 ->andWhere('th.createdBy = :createdBy')
  1316.                 ->setParameter('createdBy','agent')
  1317.                 ->setParameter('ticketId',$ticketId)
  1318.                 ->setParameter('roles'4)
  1319.                 ->orderBy('th.id''DESC');
  1320.         $result $qb->getQuery()->setMaxResults(1)->getResult();
  1321.         return $result $result[0] : null;
  1322.     }
  1323.     public function getLastReply($ticketId$userType null
  1324.     {
  1325.         $queryBuilder $this->entityManager->createQueryBuilder();
  1326.         $queryBuilder->select("th, a, u.id as userId")
  1327.             ->from(Thread::class, 'th')
  1328.             ->leftJoin('th.ticket','t')
  1329.             ->leftJoin('th.attachments''a')
  1330.             ->leftJoin('th.user','u')
  1331.             ->andWhere('t.id = :ticketId')
  1332.             ->andWhere('th.threadType = :threadType')
  1333.             ->setParameter('threadType','reply')
  1334.             ->setParameter('ticketId',$ticketId)
  1335.             ->orderBy('th.id''DESC')
  1336.             ->getMaxResults(1);
  1337.         if (!empty($userType)) {
  1338.             $queryBuilder->andWhere('th.createdBy = :createdBy')->setParameter('createdBy'$userType);
  1339.         }
  1340.         
  1341.         $threadResponse $queryBuilder->getQuery()->getArrayResult();
  1342.         
  1343.         if (!empty($threadResponse[0][0])) {
  1344.             $threadDetails $threadResponse[0][0];
  1345.             $userService $this->container->get('user.service');
  1346.             
  1347.             if ($threadDetails['createdBy'] == 'agent') {
  1348.                 $threadDetails['user'] = $userService->getAgentDetailById($threadResponse[0]['userId']);
  1349.             } else {
  1350.                 $threadDetails['user'] = $userService->getCustomerPartialDetailById($threadResponse[0]['userId']);
  1351.             }
  1352.             
  1353.             $threadDetails['reply'] = html_entity_decode($threadDetails['message']);
  1354.             $threadDetails['formatedCreatedAt'] = $this->timeZoneConverter($threadDetails['createdAt']);
  1355.             $threadDetails['timestamp'] = $userService->convertToDatetimeTimezoneTimestamp($threadDetails['createdAt']);
  1356.             if (!empty($threadDetails['attachments'])) {
  1357.                 $entityManager $this->entityManager;
  1358.                 $uvdeskFileSystemService $this->container->get('uvdesk.core.file_system.service');
  1359.                 $threadDetails['attachments'] = array_map(function ($attachment) use ($entityManager$uvdeskFileSystemService) {
  1360.                     $attachmentReferenceObject $this->entityManager->getReference(Attachment::class, $attachment['id']);
  1361.                     return $uvdeskFileSystemService->getFileTypeAssociations($attachmentReferenceObject);
  1362.                 }, $threadDetails['attachments']);
  1363.             }
  1364.         }
  1365.         return $threadDetails ?? null;
  1366.     }
  1367.     public function getSavedReplyContent($savedReplyId$ticketId)
  1368.     {
  1369.         $ticket $this->entityManager->getRepository(Ticket::class)->find($ticketId);
  1370.         $savedReply $this->entityManager->getRepository(SavedReplies::class)->findOneById($savedReplyId);
  1371.         $emailPlaceholders $this->getSavedReplyPlaceholderValues($ticket'customer');
  1372.         return $this->container->get('email.service')->processEmailContent($savedReply->getMessage(), $emailPlaceholderstrue);
  1373.     }
  1374.     public function getSavedReplyPlaceholderValues($ticket$type "customer")
  1375.     {
  1376.         $variables = array();
  1377.         $variables['ticket.id'] = $ticket->getId();
  1378.         $variables['ticket.subject'] = $ticket->getSubject();
  1379.         $variables['ticket.status'] = $ticket->getStatus()->getCode();
  1380.         $variables['ticket.priority'] = $ticket->getPriority()->getCode();
  1381.         if($ticket->getSupportGroup())
  1382.             $variables['ticket.group'] = $ticket->getSupportGroup()->getName();
  1383.         else
  1384.             $variables['ticket.group'] = '';
  1385.         $variables['ticket.team'] = ($ticket->getSupportTeam() ? $ticket->getSupportTeam()->getName() : '');
  1386.         $customer $this->container->get('user.service')->getCustomerPartialDetailById($ticket->getCustomer()->getId());
  1387.         $variables['ticket.customerName'] = $customer['name'];
  1388.         $variables['ticket.customerEmail'] = $customer['email'];
  1389.         $userService $this->container->get('user.service');
  1390.       
  1391.         $variables['ticket.agentName'] = '';
  1392.         $variables['ticket.agentEmail'] = '';
  1393.         if ($ticket->getAgent()) {
  1394.             $agent $this->container->get('user.service')->getAgentDetailById($ticket->getAgent()->getId());
  1395.             if($agent) {
  1396.                 $variables['ticket.agentName'] = $agent['name'];
  1397.                 $variables['ticket.agentEmail'] = $agent['email'];
  1398.             }
  1399.         }
  1400.         
  1401.         $router $this->container->get('router');
  1402.         if ($type == 'customer') {
  1403.             $ticketListURL $router->generate('helpdesk_customer_ticket_collection', [
  1404.                 'id' => $ticket->getId(),
  1405.             ], UrlGeneratorInterface::ABSOLUTE_URL);
  1406.         } else {
  1407.             $ticketListURL $router->generate('helpdesk_member_ticket_collection', [
  1408.                 'id' => $ticket->getId(),
  1409.             ], UrlGeneratorInterface::ABSOLUTE_URL);
  1410.         }
  1411.         $variables['ticket.link'] = sprintf("<a href='%s'>#%s</a>"$ticketListURL$ticket->getId());
  1412.         return $variables;
  1413.     }
  1414.     public function isEmailBlocked($email$website
  1415.     {
  1416.         $flag false;
  1417.         $email strtolower($email);
  1418.         $knowlegeBaseWebsite $this->entityManager->getRepository(KnowledgebaseWebsite::class)->findOneBy(['website' => $website->getId(), 'isActive' => 1]);
  1419.         $list $this->container->get('user.service')->getWebsiteSpamDetails($knowlegeBaseWebsite);
  1420.         // Blacklist
  1421.         if (!empty($list['blackList']['email']) && in_array($email$list['blackList']['email'])) {
  1422.             // Emails
  1423.             $flag true;
  1424.         } elseif (!empty($list['blackList']['domain'])) {
  1425.             // Domains
  1426.             foreach ($list['blackList']['domain'] as $domain) {
  1427.                 if (strpos($email$domain)) {
  1428.                     $flag true;
  1429.                     break;
  1430.                 }
  1431.             }
  1432.         }
  1433.         // Whitelist
  1434.         if ($flag) {
  1435.             if (isset($email$list['whiteList']['email']) && in_array($email$list['whiteList']['email'])) {
  1436.                 // Emails
  1437.                 return false;
  1438.             } elseif (isset($list['whiteList']['domain'])) {
  1439.                 // Domains
  1440.                 foreach ($list['whiteList']['domain'] as $domain) {
  1441.                     if (strpos($email$domain)) {
  1442.                         $flag false;
  1443.                     }
  1444.                 }
  1445.             }
  1446.         }
  1447.         return $flag;
  1448.     }
  1449.     public function timeZoneConverter($dateFlag)
  1450.     {
  1451.         $website $this->entityManager->getRepository(Website::class)->findOneBy(['code' => 'Knowledgebase']);
  1452.         $timeZone $website->getTimezone();
  1453.         $timeFormat $website->getTimeformat();
  1454.         $activeUser $this->container->get('user.service')->getSessionUser();
  1455.         $agentTimeZone = !empty($activeUser) ? $activeUser->getTimezone() : null;
  1456.         $agentTimeFormat = !empty($activeUser) ? $activeUser->getTimeformat() : null;
  1457.         $parameterType gettype($dateFlag);
  1458.         if($parameterType == 'string'){
  1459.             if(is_null($agentTimeZone) && is_null($agentTimeFormat)){
  1460.                 if(is_null($timeZone) && is_null($timeFormat)){
  1461.                     $datePattern date_create($dateFlag);
  1462.                     return date_format($datePattern,'d-m-Y h:ia');
  1463.                 } else {
  1464.                     $dateFlag = new \DateTime($dateFlag);
  1465.                     $datePattern $dateFlag->setTimezone(new \DateTimeZone($timeZone));
  1466.                     return date_format($datePattern$timeFormat);
  1467.                 }
  1468.             } else {
  1469.                 $dateFlag = new \DateTime($dateFlag);
  1470.                 $datePattern $dateFlag->setTimezone(new \DateTimeZone($agentTimeZone));
  1471.                 return date_format($datePattern$agentTimeFormat);
  1472.             }          
  1473.         } else {
  1474.             if(is_null($agentTimeZone) && is_null($agentTimeFormat)){
  1475.                 if(is_null($timeZone) && is_null($timeFormat)){
  1476.                     return date_format($dateFlag,'d-m-Y h:ia');
  1477.                 } else {
  1478.                     $datePattern $dateFlag->setTimezone(new \DateTimeZone($timeZone));
  1479.                     return date_format($datePattern$timeFormat);
  1480.                 }
  1481.             } else {
  1482.                 $datePattern $dateFlag->setTimezone(new \DateTimeZone($agentTimeZone));
  1483.                 return date_format($datePattern$agentTimeFormat);
  1484.             }    
  1485.         }         
  1486.     }
  1487.     public function fomatTimeByPreference($dbTime,$timeZone,$timeFormat,$agentTimeZone,$agentTimeFormat)
  1488.     {
  1489.         if(is_null($agentTimeZone) && is_null($agentTimeFormat)) {
  1490.             if(is_null($timeZone) && is_null($timeFormat)){
  1491.                 $dateTimeZone $dbTime;
  1492.                 $timeFormatString 'd-m-Y h:ia';
  1493.             } else {
  1494.                 $dateTimeZone $dbTime->setTimezone(new \DateTimeZone($timeZone));
  1495.                 $timeFormatString $timeFormat;
  1496.             }
  1497.         } else {
  1498.             $dateTimeZone $dbTime->setTimezone(new \DateTimeZone($agentTimeZone));
  1499.             $timeFormatString $agentTimeFormat;
  1500.         }
  1501.         $time['dateTimeZone'] = $dateTimeZone;
  1502.         $time['timeFormatString'] = $timeFormatString;
  1503.         return $time;
  1504.     }
  1505.     
  1506.     public function isTicketAccessGranted(Ticket $ticketUser $user null$firewall 'members')
  1507.     {
  1508.         // @TODO: Take current firewall into consideration (access check on behalf of agent/customer)
  1509.         if (empty($user)) {
  1510.             $user $this->container->get('user.service')->getSessionUser();
  1511.         }
  1512.         if (empty($user)) {
  1513.             return false;
  1514.         } else {
  1515.             $agentInstance $user->getAgentInstance();
  1516.     
  1517.             if (empty($agentInstance)) {
  1518.                 return false;
  1519.             }
  1520.         }
  1521.         if ($agentInstance->getSupportRole()->getId() == && in_array($agentInstance->getTicketAccessLevel(), [234])) {
  1522.             $accessLevel $agentInstance->getTicketAccessLevel();
  1523.             // Check if user has been given inidividual access
  1524.             if ($ticket->getAgent() != null && $ticket->getAgent()->getId() == $user->getId()) {
  1525.                 return true;
  1526.             }
  1527.             
  1528.             if ($accessLevel == || $accessLevel == 3) {
  1529.                 // Check if user belongs to a support team assigned to ticket
  1530.                 $teamReferenceIds array_map(function ($team) { return $team->getId(); }, $agentInstance->getSupportTeams()->toArray());
  1531.                 
  1532.                 if ($ticket->getSupportTeam() != null && in_array($ticket->getSupportTeam()->getId(), $teamReferenceIds)) {
  1533.                     return true;
  1534.                 } else if ($accessLevel == 2) {
  1535.                     // Check if user belongs to a support group assigned to ticket
  1536.                     $groupReferenceIds array_map(function ($group) { return $group->getId(); }, $agentInstance->getSupportGroups()->toArray());
  1537.                     if ($ticket->getSupportGroup() != null && in_array($ticket->getSupportGroup()->getId(), $groupReferenceIds)) {
  1538.                         return true;
  1539.                     }
  1540.                 }
  1541.             }
  1542.             return false;
  1543.         }
  1544.         return true;
  1545.     }
  1546.     public function addTicketCustomFields($thread$requestCustomFields = [], $filesCustomFields = [])
  1547.     {
  1548.         $ticket $thread->getTicket();
  1549.         $skipFileUpload false;
  1550.         $customFieldsCollection $this->entityManager->getRepository(CommunityPackageEntities\CustomFields::class)->findAll();
  1551.         foreach ($customFieldsCollection as $customFields) {
  1552.             if(in_array($customFields->getFieldType(), ['select''checkbox''radio']) && !count($customFields->getCustomFieldValues()))
  1553.                 continue;
  1554.             elseif('file' != $customFields->getFieldType() && $requestCustomFields && array_key_exists($customFields->getId(), $requestCustomFields) && $requestCustomFields[$customFields->getId()]) {
  1555.                 if(count($customFields->getCustomFieldsDependency()) && !in_array($ticket->getType(), $customFields->getCustomFieldsDependency()->toArray()))
  1556.                     continue;
  1557.                 $ticketCustomField = new CommunityPackageEntities\TicketCustomFieldsValues();
  1558.                 $ticketCustomField->setTicket($ticket);
  1559.                 //custom field
  1560.                 $ticketCustomField->setTicketCustomFieldsValues($customFields);
  1561.                 $ticketCustomField->setValue(json_encode($requestCustomFields[$customFields->getId()]));
  1562.                 if(in_array($customFields->getFieldType(), ['select''checkbox''radio'])) {
  1563.                     //add custom field values mapping too
  1564.                     if(is_array($requestCustomFields[$customFields->getId()])) {
  1565.                         foreach ($requestCustomFields[$customFields->getId()] as $value) {
  1566.                             if($ticketCustomFieldValues $this->entityManager->getRepository(CommunityPackageEntities\CustomFieldsValues::class)
  1567.                                 ->findOneBy(['customFields' => $customFields'id' => $value]))
  1568.                                 $ticketCustomField->setTicketCustomFieldValueValues($ticketCustomFieldValues);
  1569.                         }
  1570.                     } elseif($ticketCustomFieldValues $this->entityManager->getRepository(CommunityPackageEntities\CustomFieldsValues::class)
  1571.                             ->findOneBy(['customFields' => $customFields'id' => $requestCustomFields[$customFields->getId()]]))                                                        
  1572.                         $ticketCustomField->setTicketCustomFieldValueValues($ticketCustomFieldValues);
  1573.                 }
  1574.                 $this->entityManager->persist($ticketCustomField);
  1575.                 $this->entityManager->flush();
  1576.             } elseif($filesCustomFields && array_key_exists($customFields->getId(), $filesCustomFields) && $filesCustomFields[$customFields->getId()] && !$skipFileUpload) {
  1577.                 $skipFileUpload true;
  1578.                 //upload files
  1579.             
  1580.                 $path '/custom-fields/ticket/' $ticket->getId() . '/';
  1581.                 $fileNames $this->fileUploadService->uploadFile($filesCustomFields[$customFields->getid()], $pathtrue);
  1582.                 if(!empty($fileNames)) {
  1583.                     //save files entry to attachment table
  1584.                     try {
  1585.                         $customFieldsService null;
  1586.                         try {
  1587.                             if ($this->userService->isfileExists('apps/uvdesk/custom-fields')) {
  1588.                                 $customFieldsService $this->get('uvdesk_package_custom_fields.service');
  1589.                             } else if ($this->userService->isfileExists('apps/uvdesk/form-component')) {
  1590.                                 $customFieldsService $this->get('uvdesk_package_form_component.service');
  1591.                             }
  1592.                         } catch (\Exception $e) {
  1593.                             // @TODO: Log execption message
  1594.                         }
  1595.                         $newFilesNames = !empty($customFieldsService) ? $customFieldsService->addFilesEntryToAttachmentTable([$fileNames], $thread) : [];
  1596.                         foreach ($newFilesNames as $value) {
  1597.                             $ticketCustomField = new CommunityPackageEntities\TicketCustomFieldsValues();
  1598.                             $ticketCustomField->setTicket($ticket);
  1599.                             //custom field
  1600.                             $ticketCustomField->setTicketCustomFieldsValues($customFields);
  1601.                             $ticketCustomField->setValue(json_encode(['name' => $value['name'], 'path' => $value['path'], 'id' => $value['id']]));
  1602.                             $this->entityManager->persist($ticketCustomField);
  1603.                             $this->entityManager->flush();
  1604.                         }
  1605.                     } catch (\Exception $e) {
  1606.                         // @TODO: Log execption message
  1607.                     }
  1608.                 }
  1609.             }
  1610.         }
  1611.     }
  1612.     // return attachemnt for initial thread
  1613.     public function getInitialThread($ticketId)
  1614.     {
  1615.         $firstThread null;
  1616.         $intialThread $this->entityManager->getRepository(Thread::class)->findBy(['ticket'=>$ticketId]);
  1617.         foreach ($intialThread as $key => $value) {
  1618.             if($value->getThreadType() == "create"){
  1619.                 $firstThread $value;
  1620.             }
  1621.         }
  1622.         return $firstThread;
  1623.     }
  1624. }