vendor/uvdesk/core-framework/Services/EmailService.php line 524

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\CoreFrameworkBundle\Services;
  3. use Symfony\Component\Mime\Email;
  4. use Symfony\Component\Mime\Address;
  5. use Symfony\Component\Mailer\Transport;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use Symfony\Component\DependencyInjection\ContainerInterface;
  8. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  9. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  10. use Webkul\UVDesk\MailboxBundle\Services\MailboxService;
  11. use Webkul\UVDesk\CoreFrameworkBundle\Utils\TokenGenerator;
  12. use Webkul\UVDesk\CoreFrameworkBundle\Services\MicrosoftIntegration;
  13. use Webkul\UVDesk\CoreFrameworkBundle\Entity as CoreFrameworkBundleEntity;
  14. use Webkul\UVDesk\CoreFrameworkBundle\Utils\Microsoft\Graph as MicrosoftGraph;
  15. use Webkul\UVDesk\MailboxBundle\Utils\SMTP\Transport\AppTransportConfigurationInterface;
  16. class EmailService
  17. {
  18.     private $container;
  19.     private $entityManager;
  20.     private $session;
  21.     private $mailboxService;
  22.     private $microsoftIntegration;
  23.     public function __construct(ContainerInterface $containerEntityManagerInterface $entityManagerSessionInterface $sessionMailboxService $mailboxServiceMicrosoftIntegration $microsoftIntegration)
  24.     {
  25.         $this->container $container;
  26.         $this->entityManager $entityManager;
  27.         $this->session $session;
  28.         $this->mailboxService $mailboxService;
  29.         $this->microsoftIntegration $microsoftIntegration;
  30.     }
  31.     public function trans($text)
  32.     {
  33.         return $this->container->get('translator')->trans($text);
  34.     }
  35.     public function getEmailPlaceHolders($params)
  36.     {
  37.         $placeHolders = [];
  38.         $template is_array($params) ? ($params['match'] . 'Note') : (!empty($params) ? $params 'template');
  39.         if ($template == 'template') {
  40.             $placeHolders = [
  41.                 'ticket' => [
  42.                     'id' => [
  43.                         'title' => $this->trans('Ticket Id'),
  44.                         'info'  => $this->trans('ticket.id.placeHolders.info'),
  45.                     ],
  46.                     'subject' => [
  47.                         'title' => $this->trans('Ticket Subject'),
  48.                         'info'  => $this->trans('ticket.subject.placeHolders.info'),
  49.                     ],
  50.                     'message' => [
  51.                         'title' => $this->trans('Ticket Message'),
  52.                         'info'  => $this->trans('ticket.message.placeHolders.info'),
  53.                     ],
  54.                     'attachments' => [
  55.                         'title' => $this->trans('Ticket Attachments'),
  56.                         'info'  => $this->trans('ticket.attachments.placeHolders.info'),
  57.                     ],
  58.                     'threadMessage' => [
  59.                         'title' => $this->trans('Ticket Thread Message'),
  60.                         'info'  => $this->trans('ticket.threadMessage.placeHolders.info'),
  61.                     ],
  62.                     'tags' => [
  63.                         'title' => $this->trans('Ticket Tags'),
  64.                         'info'  => $this->trans('ticket.tags.placeHolders.info'),
  65.                     ],
  66.                     'source' => [
  67.                         'title' => $this->trans('Ticket Source'),
  68.                         'info'  => $this->trans('ticket.source.placeHolders.info'),
  69.                     ],
  70.                     'status' => [
  71.                         'title' => $this->trans('Ticket Status'),
  72.                         'info'  => $this->trans('ticket.status.placeHolders.info'),
  73.                     ],
  74.                     'priority' => [
  75.                         'title' => $this->trans('Ticket Priority'),
  76.                         'info'  => $this->trans('ticket.priority.placeHolders.info'),
  77.                     ],
  78.                     'group' => [
  79.                         'title' => $this->trans('Ticket Group'),
  80.                         'info'  => $this->trans('ticket.group.placeHolders.info'),
  81.                     ],
  82.                     'team' => [
  83.                         'title' => $this->trans('Ticket Team'),
  84.                         'info'  => $this->trans('ticket.team.placeHolders.info'),
  85.                     ],
  86.                     'customerName' => [
  87.                         'title' => $this->trans('Ticket Customer Name'),
  88.                         'info'  => $this->trans('ticket.customerName.placeHolders.info'),
  89.                     ],
  90.                     'customerEmail' => [
  91.                         'title' => $this->trans('Ticket Customer Email'),
  92.                         'info'  => $this->trans('ticket.customerEmail.placeHolders.info'),
  93.                     ],
  94.                     'agentName' => [
  95.                         'title' => $this->trans('Ticket Agent Name'),
  96.                         'info'  => $this->trans('ticket.agentName.placeHolders.info'),
  97.                     ],
  98.                     'agentEmail' => [
  99.                         'title' => $this->trans('Ticket Agent Email'),
  100.                         'info'  => $this->trans('ticket.agentEmail.placeHolders.info'),
  101.                     ],
  102.                     'agentLink' => [
  103.                         'title' => $this->trans('Ticket Agent Link'),
  104.                         'info'  => $this->trans('ticket.link.placeHolders.info'),
  105.                     ],
  106.                     'customerLink' => [
  107.                         'title' => $this->trans('Ticket Customer Link'),
  108.                         'info'  => $this->trans('ticket.link.placeHolders.info'),
  109.                     ],
  110.                     'collaboratorName' => [
  111.                         'title' => $this->trans('Last Collaborator Name'),
  112.                         'info'  => $this->trans('ticket.collaborator.name.placeHolders.info'),
  113.                     ],
  114.                     'collaboratorEmail' => [
  115.                         'title' => $this->trans('Last Collaborator Email'),
  116.                         'info'  => $this->trans('ticket.collaborator.email.placeHolders.info'),
  117.                     ],
  118.                 ],
  119.                 'user'  => [
  120.                     'userName' => [
  121.                         'title' => $this->trans('Agent/ Customer Name'),
  122.                         'info'  => $this->trans('user.name.info'),
  123.                     ],
  124.                     'userEmail' => [
  125.                         'title' => $this->trans('Email'),
  126.                         'info'  => $this->trans('user.email.info'),
  127.                     ],
  128.                     'accountValidationLink' => [
  129.                         'title' => $this->trans('Account Validation Link'),
  130.                         'info'  => $this->trans('user.account.validate.link.info'),
  131.                     ],
  132.                     'forgotPasswordLink' => [
  133.                         'title' => $this->trans('Password Forgot Link'),
  134.                         'info'  => $this->trans('user.password.forgot.link.info'),
  135.                     ],
  136.                 ],
  137.                 'global' => [
  138.                     'companyName' => [
  139.                         'title' => $this->trans('Company Name'),
  140.                         'info'  => $this->trans('global.companyName'),
  141.                     ],
  142.                     'companyLogo' => [
  143.                         'title' => $this->trans('Company Logo'),
  144.                         'info'  => $this->trans('global.companyLogo'),
  145.                     ],
  146.                     'companyUrl' => [
  147.                         'title' => $this->trans('Company URL'),
  148.                         'info'  => $this->trans('global.companyUrl'),
  149.                     ],
  150.                 ],
  151.             ];
  152.         } elseif ($template == 'savedReply') {
  153.             $placeHolders = [
  154.                 'ticket' => [
  155.                     'id' => [
  156.                         'title' => $this->trans('Ticket Id'),
  157.                         'info'  => $this->trans('ticket.id.placeHolders.info'),
  158.                     ],
  159.                     'subject' => [
  160.                         'title' => $this->trans('Ticket Subject'),
  161.                         'info'  => $this->trans('ticket.subject.placeHolders.info'),
  162.                     ],
  163.                     'status' => [
  164.                         'title' => $this->trans('Ticket Status'),
  165.                         'info'  => $this->trans('ticket.status.placeHolders.info'),
  166.                     ],
  167.                     'priority' => [
  168.                         'title' => $this->trans('Ticket Priority'),
  169.                         'info'  => $this->trans('ticket.priority.placeHolders.info'),
  170.                     ],
  171.                     'group' => [
  172.                         'title' => $this->trans('Ticket Group'),
  173.                         'info'  => $this->trans('ticket.group.placeHolders.info'),
  174.                     ],
  175.                     'team' => [
  176.                         'title' => $this->trans('Ticket Team'),
  177.                         'info'  => $this->trans('ticket.team.placeHolders.info'),
  178.                     ],
  179.                     'customerName' => [
  180.                         'title' => $this->trans('Ticket Customer Name'),
  181.                         'info'  => $this->trans('ticket.customerName.placeHolders.info'),
  182.                     ],
  183.                     'customerEmail' => [
  184.                         'title' => $this->trans('Ticket Customer Email'),
  185.                         'info'  => $this->trans('ticket.customerEmail.placeHolders.info'),
  186.                     ],
  187.                     'agentName' => [
  188.                         'title' => $this->trans('Ticket Agent Name'),
  189.                         'info'  => $this->trans('ticket.agentName.placeHolders.info'),
  190.                     ],
  191.                     'agentEmail' => [
  192.                         'title' => $this->trans('Ticket Agent Email'),
  193.                         'info'  => $this->trans('ticket.agentEmail.placeHolders.info'),
  194.                     ],
  195.                     'link' => [
  196.                         'title' => $this->trans('Ticket Link'),
  197.                         'info'  => $this->trans('ticket.link.placeHolders.info'),
  198.                     ],
  199.                 ],
  200.             ];
  201.         } elseif ($template == 'ticketNote') {
  202.             $placeHolders = [
  203.                 'type' => [
  204.                     'previousType' => [
  205.                         'title' => $this->trans('Previous Type'),
  206.                         'info'  => $this->trans('type.previous.placeHolders.info'),
  207.                     ],
  208.                     'updatedType' => [
  209.                         'title' => $this->trans('Updated Type'),
  210.                         'info'  => $this->trans('type.updated.placeHolders.info'),
  211.                     ],
  212.                 ],
  213.                 'status' => [
  214.                     'previousStatus' => [
  215.                         'title' => $this->trans('Previous Status'),
  216.                         'info'  => $this->trans('status.previous.placeHolders.info'),
  217.                     ],
  218.                     'updatedStatus' => [
  219.                         'title' => $this->trans('Updated Status'),
  220.                         'info'  => $this->trans('status.updated.placeHolders.info'),
  221.                     ],
  222.                 ],
  223.                 'group' => [
  224.                     'previousGroup' => [
  225.                         'title' => $this->trans('Previous Group'),
  226.                         'info'  => $this->trans('group.previous.placeHolders.info'),
  227.                     ],
  228.                     'updatedGroup' => [
  229.                         'title' => $this->trans('Updated Group'),
  230.                         'info'  => $this->trans('group.updated.placeHolders.info'),
  231.                     ],
  232.                 ],
  233.                 'team' => [
  234.                     'previousTeam' => [
  235.                         'title' => $this->trans('Previous Team'),
  236.                         'info'  => $this->trans('team.previous.placeHolders.info'),
  237.                     ],
  238.                     'updatedTeam' => [
  239.                         'title' => $this->trans('Updated Team'),
  240.                         'info'  => $this->trans('team.updated.placeHolders.info'),
  241.                     ],
  242.                 ],
  243.                 'priority' => [
  244.                     'previousPriority' => [
  245.                         'title' => $this->trans('Previous Priority'),
  246.                         'info'  => $this->trans('priority.previous.placeHolders.info'),
  247.                     ],
  248.                     'updatedPriority' => [
  249.                         'title' => $this->trans('Updated Priority'),
  250.                         'info'  => $this->trans('priority.updated.placeHolders.info'),
  251.                     ],
  252.                 ],
  253.                 'agent' => [
  254.                     'previousAgent' => [
  255.                         'title' => $this->trans('Previous Agent'),
  256.                         'info'  => $this->trans('agent.previous.placeHolders.info'),
  257.                     ],
  258.                     'updatedAgent' => [
  259.                         'title' => $this->trans('Updated Agent'),
  260.                         'info'  => $this->trans('agent.updated.placeHolders.info'),
  261.                     ],
  262.                     'responsePerformingAgent' => [
  263.                         'title' => $this->trans('Response Performing Agent'),
  264.                         'info'  => $this->trans('agent.response.placeHolders.info'),
  265.                     ],
  266.                 ],
  267.             ];
  268.         } elseif ($template == 'manualNote') {
  269.             $placeHolders = [
  270.                 'ticket' => [
  271.                     'id' => [
  272.                         'title' => $this->trans('Ticket Id'),
  273.                         'info'  => $this->trans('ticket.id.placeHolders.info'),
  274.                     ],
  275.                     'subject' => [
  276.                         'title' => $this->trans('Ticket Subject'),
  277.                         'info'  => $this->trans('ticket.subject.placeHolders.info'),
  278.                     ],
  279.                     'status' => [
  280.                         'title' => $this->trans('Ticket Status'),
  281.                         'info'  => $this->trans('ticket.status.placeHolders.info'),
  282.                     ],
  283.                     'priority' => [
  284.                         'title' => $this->trans('Ticket Priority'),
  285.                         'info'  => $this->trans('ticket.priority.placeHolders.info'),
  286.                     ],
  287.                     'group' => [
  288.                         'title' => $this->trans('Ticket Group'),
  289.                         'info'  => $this->trans('ticket.group.placeHolders.info'),
  290.                     ],
  291.                     'team' => [
  292.                         'title' => $this->trans('Ticket Team'),
  293.                         'info'  => $this->trans('ticket.team.placeHolders.info'),
  294.                     ],
  295.                     'customerName' => [
  296.                         'title' => $this->trans('Ticket Customer Name'),
  297.                         'info'  => $this->trans('ticket.customerName.placeHolders.info'),
  298.                     ],
  299.                     'customerEmail' => [
  300.                         'title' => $this->trans('Ticket Customer Email'),
  301.                         'info'  => $this->trans('ticket.customerEmail.placeHolders.info'),
  302.                     ],
  303.                     'agentName' => [
  304.                         'title' => $this->trans('Ticket Agent Name'),
  305.                         'info'  => $this->trans('ticket.agentName.placeHolders.info'),
  306.                     ],
  307.                     'agentEmail' => [
  308.                         'title' => $this->trans('Ticket Agent Email'),
  309.                         'info'  => $this->trans('ticket.agentEmail.placeHolders.info'),
  310.                     ],
  311.                 ],
  312.             ];
  313.         }
  314.         return $placeHolders;
  315.     }
  316.     public function getEmailPlaceholderValues(CoreFrameworkBundleEntity\User $user)
  317.     {
  318.         if (null == $user->getVerificationCode()) {
  319.             // Set user verification code
  320.             $user->setVerificationCode(TokenGenerator::generateToken());
  321.             $this->entityManager->persist($user);
  322.             $this->entityManager->flush();
  323.         }
  324.         $router $this->container->get('router');
  325.         $helpdeskWebsite $this->entityManager->getRepository(CoreFrameworkBundleEntity\Website::class)->findOneByCode('helpdesk');
  326.         // Link to company knowledgebase
  327.         if (false == array_key_exists('UVDeskSupportCenterBundle'$this->container->getParameter('kernel.bundles'))) {
  328.             $companyURL $this->container->getParameter('uvdesk.site_url');
  329.         } else {
  330.             $companyURL $router->generate('helpdesk_knowledgebase', [], UrlGeneratorInterface::ABSOLUTE_URL);
  331.         }
  332.         $currentRequest $this->container->get('request_stack')->getCurrentRequest();
  333.         // Determine the scheme based on the current request
  334.         $scheme $currentRequest && $currentRequest->isSecure() ? 'https://' 'http://';
  335.         // Link to update account login credentials
  336.         $updateCredentialsURL preg_replace(
  337.             '/^https?:\/\//',
  338.             $scheme,
  339.             $router->generate('helpdesk_update_account_credentials', [
  340.                 'email' => $user->getEmail(),
  341.                 'verificationCode' => $user->getVerificationCode(),
  342.             ], UrlGeneratorInterface::ABSOLUTE_URL)
  343.         );
  344.         $companyUrl preg_replace(
  345.             '/^https?:\/\//',
  346.             $scheme,
  347.             $companyURL
  348.         );
  349.         $placeholderParams = [
  350.             'user.userName'              => $user->getFullName(),
  351.             'user.userEmail'             => $user->getEmail(),
  352.             'user.assignUserEmail'       => $user->getEmail(),
  353.             'user.forgotPasswordLink'    => $updateCredentialsURL,
  354.             'user.accountValidationLink' => $updateCredentialsURL,
  355.             'global.companyName'         => $helpdeskWebsite->getName(),
  356.             'global.companyLogo'         => "<img src='cid:companyLogo' height='60 style='display:block; height:60px; max-height:60px; width:auto;' />",
  357.             'global.companyUrl'          => "<a href='$companyUrl'>$companyURL</a>",
  358.         ];
  359.         return $placeholderParams;
  360.     }
  361.     public function getTicketPlaceholderValues(CoreFrameworkBundleEntity\Ticket $ticket)
  362.     {
  363.         $viewTicketURL '';
  364.         $generateTicketURLCustomer '';
  365.         $supportTeam $ticket->getSupportTeam();
  366.         $supportGroup $ticket->getSupportGroup();
  367.         $supportTags array_map(function ($supportTag) {
  368.             return $supportTag->getName();
  369.         }, $ticket->getSupportTags()->toArray());
  370.         $router $this->container->get('router');
  371.         $helpdeskWebsite $this->entityManager->getRepository(CoreFrameworkBundleEntity\Website::class)->findOneByCode('helpdesk');
  372.         // Link to company knowledgebase
  373.         if (false == array_key_exists('UVDeskSupportCenterBundle'$this->container->getParameter('kernel.bundles'))) {
  374.             $companyURL $this->container->getParameter('uvdesk.site_url');
  375.         } else {
  376.             $companyURL $router->generate('helpdesk_knowledgebase', [], UrlGeneratorInterface::ABSOLUTE_URL);
  377.         }
  378.         $customerPartialDetails $ticket->getCustomer()->getCustomerInstance()->getPartialDetails();
  379.         $agentPartialDetails $ticket->getAgent() ? $ticket->getAgent()->getAgentInstance()->getPartialDetails() : null;
  380.         $currentRequest $this->container->get('request_stack')->getCurrentRequest();
  381.         // Determine the scheme based on the current request
  382.         $scheme $currentRequest && $currentRequest->isSecure() ? 'https://' 'http://';
  383.         $companyURL preg_replace(
  384.             '/^https?:\/\//',
  385.             $scheme,
  386.             $companyURL
  387.         );
  388.         //Ticket Url and create ticket url for agent
  389.         $viewTicketURLAgent preg_replace(
  390.             '/^https?:\/\//',
  391.             $scheme,
  392.             $router->generate('helpdesk_member_ticket', [
  393.                 'ticketId' => $ticket->getId(),
  394.             ], UrlGeneratorInterface::ABSOLUTE_URL)
  395.         );
  396.         $generateTicketURLAgent preg_replace(
  397.             '/^https?:\/\//',
  398.             $scheme,
  399.             $router->generate(
  400.                 'helpdesk_member_create_ticket',
  401.                 [],
  402.                 UrlGeneratorInterface::ABSOLUTE_URL
  403.             )
  404.         );
  405.         if (false != array_key_exists('UVDeskSupportCenterBundle'$this->container->getParameter('kernel.bundles'))) {
  406.             $viewTicketURL preg_replace(
  407.                 '/^https?:\/\//',
  408.                 $scheme,
  409.                 $router->generate('helpdesk_customer_ticket', [
  410.                     'id' => $ticket->getId(),
  411.                 ], UrlGeneratorInterface::ABSOLUTE_URL)
  412.             );
  413.             $generateTicketURLCustomer preg_replace(
  414.                 '/^https?:\/\//',
  415.                 $scheme,
  416.                 $router->generate(
  417.                     'helpdesk_customer_create_ticket',
  418.                     [],
  419.                     UrlGeneratorInterface::ABSOLUTE_URL
  420.                 )
  421.             );
  422.         }
  423.         $placeholderParams = [
  424.             'ticket.id'                        => $ticket->getId(),
  425.             'ticket.subject'                   => $ticket->getSubject(),
  426.             'ticket.message'                   => (count($ticket->getThreads())) > preg_replace("/<img[^>]+\>/i"""$ticket->getThreads()->get(0)->getMessage()) : preg_replace("/<img[^>]+\>/i"""$this->container->get('ticket.service')->getInitialThread($ticket->getId())->getMessage()),
  427.             'ticket.threadMessage'             => $this->threadMessage($ticket),
  428.             'ticket.tags'                      => implode(','$supportTags),
  429.             'ticket.source'                    => ucfirst($ticket->getSource()),
  430.             'ticket.status'                    => $ticket->getStatus()->getDescription(),
  431.             'ticket.priority'                  => $ticket->getPriority()->getDescription(),
  432.             'ticket.team'                      => $supportTeam $supportTeam->getName() : '',
  433.             'ticket.group'                     => $supportGroup $supportGroup->getName() : '',
  434.             'ticket.customerName'              => $customerPartialDetails['name'],
  435.             'ticket.customerEmail'             => $customerPartialDetails['email'],
  436.             'ticket.agentName'                 => !empty($agentPartialDetails) ? $agentPartialDetails['name'] : '',
  437.             'ticket.agentEmail'                => !empty($agentPartialDetails) ? $agentPartialDetails['email'] : '',
  438.             'ticket.attachments'               => '',
  439.             'ticket.collaboratorName'          => $this->getCollaboratorName($ticket),
  440.             'ticket.collaboratorEmail'         => $this->getCollaboratorEmail($ticket),
  441.             'ticket.agentLink'                 => sprintf("<a href='%s'>#%s</a>"$viewTicketURLAgent$ticket->getId()),
  442.             'ticket.ticketGenerateUrlAgent'    => sprintf("<a href='%s'>click here</a>"$generateTicketURLAgent),
  443.             'ticket.customerLink'              => sprintf("<a href='%s'>#%s</a>"$viewTicketURL$ticket->getId()),
  444.             'ticket.ticketGenerateUrlCustomer' => sprintf("<a href='%s'>click here</a>"$generateTicketURLCustomer),
  445.             'global.companyName'               => $helpdeskWebsite->getName(),
  446.             'global.companyLogo'               => "<img style='max-height:60px' src='cid:companyLogo'/>",
  447.             'global.companyUrl'                => "<a href='$companyURL'>$companyURL</a>",
  448.         ];
  449.         return $placeholderParams;
  450.     }
  451.     public function threadMessage($ticket)
  452.     {
  453.         if (isset($ticket->createdThread) && $ticket->createdThread->getThreadType() != "note") {
  454.             return preg_replace("/<img[^>]+\>/i"""$ticket->createdThread->getMessage());
  455.         } elseif (isset($ticket->currentThread) && $ticket->currentThread->getThreadType() != "note") {
  456.             return  preg_replace("/<img[^>]+\>/i"""$ticket->currentThread->getMessage());
  457.         } else {
  458.             $messages $ticket->getThreads();
  459.             for ($i count($messages) - 1$i >= 0$i--) {
  460.                 if (isset($messages[$i]) && $messages[$i]->getThreadType() != "note") {
  461.                     return preg_replace("/<img[^>]+\>/i"""$messages[$i]->getMessage());
  462.                 }
  463.             }
  464.         }
  465.         return "";
  466.     }
  467.     public function processEmailSubject($subject, array $emailPlaceholders = [])
  468.     {
  469.         foreach ($emailPlaceholders as $var => $value) {
  470.             $subject strtr($subject, ["{%$var%}" => $value"{% $var %}" => $value]);
  471.         }
  472.         return $subject;
  473.     }
  474.     public function processEmailContent($content, array $emailPlaceholders = [], $isSavedReply false)
  475.     {
  476.         $twigTemplatingEngine $this->container->get('twig');
  477.         $baseEmailTemplate $this->container->getParameter('uvdesk.default.templates.email');
  478.         foreach ($emailPlaceholders as $var => $value) {
  479.             $content strtr($content, ["{%$var%}" => $value"{% $var %}" => $value]);
  480.         }
  481.         $content $isSavedReply stripslashes($content) : htmlspecialchars_decode(preg_replace(['#&lt;script&gt;#''#&lt;/script&gt;#'], ['&amp;lt;script&amp;gt;''&amp;lt;/script&amp;gt;'], $content));
  482.         return $twigTemplatingEngine->render($baseEmailTemplate, ['message' => $content]);
  483.     }
  484.     public function sendMail($subject$content$recipient, array $headers = [], $mailboxEmail null, array $attachments = [], $cc = [], $bcc = [])
  485.     {
  486.         $mailer_type $this->container->getParameter('uvdesk.support_email.mailer_type');
  487.         if (empty($mailboxEmail)) {
  488.             // Send email on behalf of support helpdesk
  489.             $supportEmail $this->container->getParameter('uvdesk.support_email.id');
  490.             $supportEmailName $this->container->getParameter('uvdesk.support_email.name');
  491.             $mailerID $this->container->getParameter('uvdesk.support_email.mailer_id');
  492.         } else {
  493.             // Register automations conditionally if AutomationBundle has been added as an dependency.
  494.             if (!array_key_exists('UVDeskMailboxBundle'$this->container->getParameter('kernel.bundles'))) {
  495.                 return;
  496.             } else {
  497.                 // Send email on behalf of configured mailbox
  498.                 try {
  499.                     $mailbox $this->container->get('uvdesk.mailbox')->getMailboxByEmail($mailboxEmail);
  500.                     if (true === $mailbox['enabled']) {
  501.                         if ($mailer_type == 'swiftmailer_id') {
  502.                             $supportEmail $mailbox['email'];
  503.                             $supportEmailName $mailbox['name'];
  504.                             $mailerID $mailbox['smtp_swift_mailer_server']['mailer_id'];
  505.                         } else {
  506.                             $supportEmail $mailbox['email'];
  507.                             $supportEmailName $mailbox['name'];
  508.                             $mailerID $this->container->getParameter('uvdesk.support_email.mailer_id');
  509.                         }
  510.                     } else {
  511.                         return;
  512.                     }
  513.                 } catch (\Exception $e) {
  514.                     // @TODO: Log exception - Mailbox not found
  515.                     return;
  516.                 }
  517.             }
  518.         }
  519.         // Send emails only if any mailer configuration is available
  520.         $mailer null;
  521.         $mailboxConfigurations $this->mailboxService->parseMailboxConfigurations();
  522.         if ($mailer_type != 'swiftmailer_id') {
  523.             $mailbox $mailboxConfigurations->getMailboxById($mailerID);
  524.             if (!$mailbox) {
  525.                 return;
  526.             }
  527.             $mailboxSmtpConfiguration $mailbox?->getSmtpConfiguration();
  528.         }
  529.         $helpdeskKnowledgebaseWebsite $this->entityManager->getRepository(CoreFrameworkBundleEntity\Website::class)->findOneByCode('knowledgebase');
  530.         if (!empty($helpdeskKnowledgebaseWebsite) && null != $helpdeskKnowledgebaseWebsite->getLogo()) {
  531.             $currentRequest $this->container->get('request_stack')->getCurrentRequest();
  532.             $scheme $currentRequest && $currentRequest->isSecure() ? 'https://' 'http://';
  533.             $companyLogoURL sprintf('https://%s%s'$this->container->getParameter('uvdesk.site_url'), $helpdeskKnowledgebaseWebsite->getLogo());
  534.             $companyLogoURL preg_replace(
  535.                 '/^https?:\/\//',
  536.                 $scheme,
  537.                 $companyLogoURL
  538.             );
  539.         }
  540.         if ($mailer_type == 'swiftmailer_id') {
  541.             // Retrieve mailer to be used for sending emails
  542.             try {
  543.                 $mailer $this->container->get('swiftmailer.mailer' . (('default' == $mailerID) ? '' ".$mailerID"));
  544.                 $mailer->getTransport()->setPassword(base64_decode($mailer->getTransport()->getPassword()));
  545.             } catch (\Exception $e) {
  546.                 // @TODO: Log exception - Mailer not found
  547.                 return;
  548.             }
  549.             // Format email address collections
  550.             $ccAddresses = [];
  551.             foreach ($cc as $_emailAddress) {
  552.                 if (strpos($_emailAddress"<") !== false && strpos($_emailAddress">") !== false) {
  553.                     $_recipientName trim(substr($_emailAddress0strpos($_emailAddress"<")));
  554.                     $_recipientAddress substr($_emailAddressstrpos($_emailAddress"<") + 1);
  555.                     $_recipientAddress substr($_recipientAddress0strpos($_recipientAddress">"));
  556.                     $ccAddresses[$_recipientAddress] = $_recipientName;
  557.                 } else {
  558.                     $ccAddresses[] = $_emailAddress;
  559.                 }
  560.             }
  561.             $bccAddresses = [];
  562.             foreach ($bcc as $_emailAddress) {
  563.                 if (strpos($_emailAddress"<") !== false && strpos($_emailAddress">") !== false) {
  564.                     $_recipientName trim(substr($_emailAddress0strpos($_emailAddress"<")));
  565.                     $_recipientAddress substr($_emailAddressstrpos($_emailAddress"<") + 1);
  566.                     $_recipientAddress substr($_recipientAddress0strpos($_recipientAddress">"));
  567.                     $bccAddresses[$_recipientAddress] = $_recipientName;
  568.                 } else {
  569.                     $bccAddresses[] = $_emailAddress;
  570.                 }
  571.             }
  572.             // Create a message
  573.             $message = (new \Swift_Message($subject))
  574.                 ->setFrom([$supportEmail => $supportEmailName])
  575.                 ->setTo($recipient)
  576.                 ->setBcc($bccAddresses)
  577.                 ->setCc($ccAddresses)
  578.                 ->setBody($content'text/html')
  579.                 ->addPart(strip_tags($content), 'text/plain');
  580.             if (!empty($companyLogoURL)) {
  581.                 try {
  582.                     $logoPath tempnam(sys_get_temp_dir(), 'company_logo');
  583.                     file_put_contents($logoPathfile_get_contents($companyLogoURL));
  584.                     $embeddedLogoCID $message->embed(\Swift_Image::fromPath($logoPath)->setFilename('logo.png'));
  585.                     // Replace <img src='cid:companyLogo'> or similar placeholder in content
  586.                     $content str_replace('cid:companyLogo'$embeddedLogoCID$content);
  587.                     $message->setBody($content'text/html');
  588.                 } catch (\Exception $e) {
  589.                     // Could log warning about logo not being embedded
  590.                 }
  591.             }
  592.             foreach ($attachments as $attachment) {
  593.                 if (!empty($attachment['path']) && !empty($attachment['name'])) {
  594.                     $message->attach(\Swift_Attachment::fromPath($attachment['path'])->setFilename($attachment['name']));
  595.                     continue;
  596.                 }
  597.                 $message->attach(\Swift_Attachment::fromPath($attachment));
  598.             }
  599.             $messageHeaders $message->getHeaders();
  600.             foreach ($headers as $headerName => $headerValue) {
  601.                 if (is_array($headerValue) && !empty($headerValue['messageId'])) {
  602.                     $headerValue $headerValue['messageId'];
  603.                 }
  604.                 if (is_array($headerValue) || empty($headerValue)) {
  605.                     continue; // Skip arrays that don't have a 'messageId'.
  606.                 }
  607.                 $messageHeaders->addTextHeader($headerName$headerValue);
  608.             }
  609.             try {
  610.                 $messageId $message->getId();
  611.                 $mailer->send($message);
  612.                 return "<$messageId>";
  613.             } catch (\Exception $e) {
  614.                 // @TODO: Log exception
  615.                 $this->session->getFlashBag()->add('warning'$this->trans('Warning! Swiftmailer not working. An error has occurred while sending emails!'));
  616.             }
  617.             return null;
  618.         } else {
  619.             // Prepare email
  620.             $email = new Email();
  621.             $email
  622.                 ->from(new Address($supportEmail$supportEmailName))
  623.                 ->subject($subject)
  624.                 ->text(strip_tags($content))
  625.                 ->html($content)
  626.             ;
  627.             // Manage email recipients
  628.             if (!empty($recipient)) {
  629.                 $email->to($recipient);
  630.             }
  631.             foreach ($cc as $emailAddress) {
  632.                 $email->addCc($emailAddress);
  633.             }
  634.             foreach ($bcc as $emailAddress) {
  635.                 $email->addBcc($emailAddress);
  636.             }
  637.             // Manage email attachments
  638.             foreach ($attachments as $attachment) {
  639.                 if (!empty($attachment['path']) && !empty($attachment['name'])) {
  640.                     $email->attachFromPath($attachment['path'], $attachment['name']);
  641.                     continue;
  642.                 }
  643.                 $email->attachFromPath($attachment);
  644.             }
  645.             // Configure email headers
  646.             $emailHeaders $email->getHeaders();
  647.             foreach ($headers as $name => $value) {
  648.                 if (is_array($value) && ! empty($value['messageId'])) {
  649.                     $value $value['messageId'];
  650.                 }
  651.                 if (is_array($value) || empty($value)) {
  652.                     continue; // Skip arrays that don't have a 'messageId'.
  653.                 }
  654.                 $emailHeaders->addTextHeader($name$value);
  655.             }
  656.             // Send email
  657.             $messageId null;
  658.             try {
  659.                 if ($mailboxSmtpConfiguration instanceof AppTransportConfigurationInterface) {
  660.                     $microsoftApp $this->entityManager->getRepository(CoreFrameworkBundleEntity\Microsoft\MicrosoftApp::class)->findOneByClientId($mailboxSmtpConfiguration->getClient());
  661.                     if (empty($microsoftApp)) {
  662.                         $this->session->getFlashBag()->add('warning'$this->trans('An unexpected error occurred while trying to send email. Please try again later.'));
  663.                         $this->session->getFlashBag()->add('warning'$this->trans('No associated microsoft apps were found for configured mailbox.'));
  664.                         return null;
  665.                     }
  666.                     $microsoftAccount $this->entityManager->getRepository(CoreFrameworkBundleEntity\Microsoft\MicrosoftAccount::class)->findOneBy([
  667.                         'email'        => $mailboxSmtpConfiguration->getUsername(),
  668.                         'microsoftApp' => $microsoftApp,
  669.                     ]);
  670.                     if (empty($microsoftAccount)) {
  671.                         $this->session->getFlashBag()->add('warning'$this->trans('An unexpected error occurred while trying to send email. Please try again later.'));
  672.                         $this->session->getFlashBag()->add('warning'$this->trans('No associated microsoft account was found for configured mailbox.'));
  673.                         return null;
  674.                     }
  675.                     $credentials json_decode($microsoftAccount->getCredentials(), true);
  676.                     $emailParams = [
  677.                         'subject' => $subject,
  678.                         'body' => [
  679.                             'contentType' => 'HTML',
  680.                             'content'     => $content,
  681.                         ],
  682.                         'toRecipients' => [
  683.                             [
  684.                                 'emailAddress' => [
  685.                                     'address' => $recipient,
  686.                                 ],
  687.                             ],
  688.                         ],
  689.                     ];
  690.                     // Download the company logo image
  691.                     $imageContent file_get_contents($companyLogoURL);
  692.                     // Convert the image to base64
  693.                     $imageBase64 base64_encode($imageContent);
  694.                     $emailParams = [
  695.                         'subject' => $subject,
  696.                         'body' => [
  697.                             'contentType' => 'HTML',
  698.                             'content' => $content// This now has <img src='cid:companyLogo'/>
  699.                         ],
  700.                         'toRecipients' => [
  701.                             [
  702.                                 'emailAddress' => [
  703.                                     'address' => $recipient,
  704.                                 ],
  705.                             ],
  706.                         ],
  707.                         'attachments' => [
  708.                             [
  709.                                 '@odata.type' => '#microsoft.graph.fileAttachment',
  710.                                 'name' => 'logo.png',
  711.                                 'contentId' => 'companyLogo',
  712.                                 'contentBytes' => $imageBase64,
  713.                             ],
  714.                         ],
  715.                     ];
  716.                     foreach ($headers as $name => $value) {
  717.                         if ($name == 'X-Transport' || empty($value)) {
  718.                             continue;
  719.                         }
  720.                         if (is_array($value)) {
  721.                             $value $value['messageId'];
  722.                         }
  723.                         $emailParams['internetMessageHeaders'][] = [
  724.                             'name' => "x-$name",
  725.                             'value' => $value,
  726.                         ];
  727.                     }
  728.                     $graphResponse MicrosoftGraph\Me::sendMail($credentials['access_token'], $emailParams);
  729.                     // Refresh access token if expired
  730.                     if (!empty($graphResponse['error'])) {
  731.                         if (!empty($graphResponse['error']['code']) && $graphResponse['error']['code'] == 'InvalidAuthenticationToken') {
  732.                             $tokenResponse $this->microsoftIntegration->refreshAccessToken($microsoftApp$credentials['refresh_token']);
  733.                             if (!empty($tokenResponse['access_token'])) {
  734.                                 $microsoftAccount
  735.                                     ->setCredentials(json_encode($tokenResponse));
  736.                                 $this->entityManager->persist($microsoftAccount);
  737.                                 $this->entityManager->flush();
  738.                                 $credentials json_decode($microsoftAccount->getCredentials(), true);
  739.                                 $graphResponse MicrosoftGraph\Me::sendMail($credentials['access_token'], $emailParams);
  740.                             }
  741.                         }
  742.                     }
  743.                 } else {
  744.                     $dsn strtr("smtp://{email}:{password}@{host}:{port}", [
  745.                         "{email}"    => $mailboxSmtpConfiguration->getUsername(),
  746.                         "{password}" => $mailboxSmtpConfiguration->getPassword(),
  747.                         "{host}"     => $mailboxSmtpConfiguration->getHost(),
  748.                         "{port}"     => $mailboxSmtpConfiguration->getPort(),
  749.                     ]);
  750.                     if (false == $mailbox->getIsStrictModeEnabled()) {
  751.                         $dsn .= "?verify_peer=0";
  752.                     }
  753.                     $transport Transport::fromDsn($dsn);
  754.                     $sentMessage $transport->send($email);
  755.                     if (!empty($sentMessage)) {
  756.                         $messageId $sentMessage->getMessageId();
  757.                     }
  758.                 }
  759.             } catch (\Exception $e) {
  760.                 // @TODO: Log exception
  761.                 $this->session->getFlashBag()->add('warning'$this->trans('An unexpected error occurred while trying to send email. Please try again later.'));
  762.                 $this->session->getFlashBag()->add('warning'$this->trans($e->getMessage()));
  763.                 return null;
  764.             }
  765.             return !empty($messageId) ? "<$messageId>" null;
  766.         }
  767.     }
  768.     public function getCollaboratorName($ticket)
  769.     {
  770.         $name null;
  771.         $ticket->lastCollaborator null;
  772.         if ($ticket->getCollaborators() != null && count($ticket->getCollaborators()) > 0) {
  773.             try {
  774.                 $ticket->lastCollaborator $ticket->getCollaborators()[-count($ticket->getCollaborators())];
  775.             } catch (\Exception $e) {
  776.             }
  777.         }
  778.         if ($ticket->lastCollaborator != null) {
  779.             $name =  $ticket->lastCollaborator->getFirstName() . " " $ticket->lastCollaborator->getLastName();
  780.         }
  781.         return $name != null $name '';
  782.     }
  783.     public function getCollaboratorEmail($ticket)
  784.     {
  785.         $email null;
  786.         $ticket->lastCollaborator null;
  787.         if ($ticket->getCollaborators() != null && count($ticket->getCollaborators()) > 0) {
  788.             try {
  789.                 $ticket->lastCollaborator $ticket->getCollaborators()[-count($ticket->getCollaborators())];
  790.             } catch (\Exception $e) {
  791.             }
  792.         }
  793.         if ($ticket->lastCollaborator != null) {
  794.             $email $ticket->lastCollaborator->getEmail();
  795.         }
  796.         return $email != null $email '';;
  797.     }
  798. }