src/FlexApp/EventSubscriber/CommentNotifyClientsSubscriber.php line 148

Open in your IDE?
  1. <?php
  2. namespace FlexApp\EventSubscriber;
  3. use Exception;
  4. use FlexApp\Classes\Constants;
  5. use FlexApp\Entity\CommentablePage;
  6. use FlexApp\Entity\CommentablePageSubscriberEntity;
  7. use FlexApp\Entity\CommentEntity;
  8. use FlexApp\Events\CommentEvent;
  9. use FlexApp\Events\Style43\CommentErrorEvent;
  10. use FlexApp\Events\Style43\NewCommentSavedEvent;
  11. use FlexApp\Exceptions\SourceByCommentTypeDefinerException;
  12. use FlexApp\Repository\CommentablePageRepository;
  13. use FlexApp\Repository\ConsultantRepository;
  14. use FlexApp\Repository\CountryAndLangSpecificDataRepository;
  15. use FlexApp\Service\ChangedUnreadCountHandler;
  16. use FlexApp\Service\ConsDefiner;
  17. use FlexApp\Service\EmailCanonicalizer;
  18. use FlexApp\Service\ManagerContactsProvider;
  19. use FlexApp\Service\ParametersProvider;
  20. use FlexApp\Service\SourceByCommentTypeDefiner;
  21. use FlexApp\Service\SystemChatNotificationService;
  22. use FlexApp\Service\TranslatorWrapper;
  23. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  24. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  25. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  26. use Symfony\Component\Routing\RouterInterface;
  27. use Twig\Environment as Twig;
  28. use WebBundle\Entity\ListEmail;
  29. use WebBundle\Helper\App;
  30. use WebBundle\Helper\Mailer;
  31. use WebBundle\Helper\UserHelper;
  32. use WebBundle\Repository\ListCountryRepository;
  33. use WebBundle\Repository\ListEmailRepository;
  34. use WebBundle\Repository\UserRepository;
  35. /**
  36.  * Слушает событие - сохранение нового коммента. По событию:
  37.  * Рассылает email-уведомления пользователям-подписчикам текущей страницы
  38.  */
  39. class CommentNotifyClientsSubscriber implements EventSubscriberInterface
  40. {
  41.     const UNSUB_SALT 'gPYfrxdQyHiQ';
  42.     /**
  43.      * @var SourceByCommentTypeDefiner
  44.      */
  45.     private $sourceByCommentTypeDefiner;
  46.     /**
  47.      * @var EventDispatcherInterface
  48.      */
  49.     private $eventDispatcher;
  50.     /**
  51.      * @var Twig
  52.      */
  53.     private $twig;
  54.     /**
  55.      * @var \FlexApp\Repository\CommentablePageRepository
  56.      */
  57.     private $commentablePageRepository;
  58.     /**
  59.      * @var Mailer
  60.      */
  61.     private $mailer;
  62.     /**
  63.      * @var ParametersProvider
  64.      */
  65.     private $parametersProvider;
  66.     /**
  67.      * @var EmailCanonicalizer
  68.      */
  69.     private $emailCanonicalizer;
  70.     /**
  71.      * @var ListEmailRepository
  72.      */
  73.     private $listEmailRepository;
  74.     /**
  75.      * @var RouterInterface
  76.      */
  77.     private $router;
  78.     /**
  79.      * @var UserRepository
  80.      */
  81.     private $userRepository;
  82.     /**
  83.      * @var SystemChatNotificationService
  84.      */
  85.     private $systemChatNotificationService;
  86.     /**
  87.      * @var \FlexApp\Service\TranslatorWrapper
  88.      */
  89.     private $translatorWrapper;
  90.     /**
  91.      * @var ChangedUnreadCountHandler
  92.      */
  93.     private $changedUnreadCountHandler;
  94.     /** @required */
  95.     public ConsultantRepository $consultantRepository;
  96.     /** @required */
  97.     public ConsDefiner $consDefiner;
  98.     /** @required */
  99.     public ListCountryRepository $listCountryRepository;
  100.     /** @required */
  101.     public CountryAndLangSpecificDataRepository $countryAndLangSpecificDataRepository;
  102.     /** @required */
  103.     public ManagerContactsProvider $contactsProvider;
  104.     public function __construct(
  105.         SourceByCommentTypeDefiner $sourceByCommentTypeDefiner,
  106.         EventDispatcherInterface $eventDispatcher,
  107.         Twig $twig,
  108.         CommentablePageRepository $commentablePageRepository,
  109.         Mailer $mailer,
  110.         ParametersProvider $parametersProvider,
  111.         EmailCanonicalizer $emailCanonicalizer,
  112.         ListEmailRepository $listEmailRepository,
  113.         RouterInterface $router,
  114.         UserRepository $userRepository,
  115.         SystemChatNotificationService $systemChatNotificationService,
  116.         TranslatorWrapper $translatorWrapper,
  117.         ChangedUnreadCountHandler $changedUnreadCountHandler
  118.     ) {
  119.         $this->sourceByCommentTypeDefiner $sourceByCommentTypeDefiner;
  120.         $this->eventDispatcher $eventDispatcher;
  121.         $this->twig $twig;
  122.         $this->commentablePageRepository $commentablePageRepository;
  123.         $this->mailer $mailer;
  124.         $this->parametersProvider $parametersProvider;
  125.         $this->emailCanonicalizer $emailCanonicalizer;
  126.         $this->listEmailRepository $listEmailRepository;
  127.         $this->router $router;
  128.         $this->userRepository $userRepository;
  129.         $this->systemChatNotificationService $systemChatNotificationService;
  130.         $this->translatorWrapper $translatorWrapper;
  131.         $this->changedUnreadCountHandler $changedUnreadCountHandler;
  132.     }
  133.     public static function getSubscribedEvents()
  134.     {
  135.         return [
  136.             NewCommentSavedEvent::class => [
  137.                 ['notifyUsers'10],
  138.             ],
  139.         ];
  140.     }
  141.     public function notifyUsers(CommentEvent $commentEvent)
  142.     {
  143.         if ('test' === $this->parametersProvider->getParameter('kernel.environment')) {
  144.             return;
  145.         }
  146.         $comment $commentEvent->getComment();
  147.         $currentUserEmail $comment->getEmail();
  148.         try {
  149.             $pageUrl $this->sourceByCommentTypeDefiner->getSourceByCommentEntity($comment);
  150.         } catch (SourceByCommentTypeDefinerException $e) {
  151.             $this->eventDispatcher->dispatch(new CommentErrorEvent(new Exception("Уведомления о новом комменте не будут разосланы: Не удалось сгенерировать ссылку для страницы коммента {$comment->getId()}{$e->getMessage()}")));
  152.             return;
  153.         }
  154.         /** @var \FlexApp\Entity\CommentablePage $commentablePage */
  155.         $commentablePage $this->commentablePageRepository->findOneBy([
  156.             'unid'   => $comment->getCommentableUnid(),
  157.             'locale' => $comment->getLocale(),
  158.             'type'   => $comment->getType(),
  159.         ]);
  160.         if (!$commentablePage) {
  161.             return;
  162.         }
  163.         /** @var ListEmail $pattern */
  164.         $pattern $this->listEmailRepository->findOneBy(['keyEmail' => 'notification_about_new_comment']);
  165.         $theme = (string)$pattern->getTitleCur($comment->getLocale());
  166.         $this->sendEmailsAndChatNotificationsToSubscribersOfCurrentPage($commentablePage$currentUserEmail$pageUrl$comment$theme$pattern);
  167.     }
  168.     private function sendEmail(string $emailstring $themestring $body)
  169.     {
  170.         try {
  171.             $this->mailer->sendEmail($theme$this->parametersProvider->getParameter('mailer_email_from'), $email$body);
  172.         } catch (Exception $e) {
  173.             $this->eventDispatcher->dispatch(new CommentErrorEvent(new Exception("Не удалось отправить письмо на '$email'")));
  174.         }
  175.     }
  176.     protected function sendEmailsAndChatNotificationsToSubscribersOfCurrentPage(
  177.         CommentablePage $commentablePage,
  178.         ?string $currentUserEmail,
  179.         string $pageUrl,
  180.         CommentEntity $comment,
  181.         string $theme,
  182.         ListEmail $pattern
  183.     ): void {
  184.         $this->consDefiner->setUseCache(false);
  185.         //Отправка уведомлений в чат
  186.         foreach ($commentablePage->getSubscribers() as $subscriber) {
  187.             /** @var CommentablePageSubscriberEntity $subscriber */
  188.             if (null === $subscriber->getToken()) {
  189.                 continue;
  190.             }
  191.             //Юзеру, который отправил текущий коммент, не отправляем уведомление в чат
  192.             if ($subscriber->getToken() !== UserHelper::getInstance()->getToken()) {
  193.                 $this->sendNotificationToChat($subscriber->getToken(), $comment);
  194.             }
  195.         }
  196.         //Отправка уведомлений на email
  197.         foreach ($commentablePage->getSubscribers() as $subscriber) {
  198.             /** @var CommentablePageSubscriberEntity $subscriber */
  199.             if (null === $subscriber->getEmailCanonical()) {
  200.                 continue;
  201.             }
  202.             $body = (string) $pattern->getBodyCur($comment->getLocale());
  203.             $body $pattern->removeMailSignature($body);
  204.             $subscriberEmail $subscriber->getEmailCanonical();
  205.             //Юзеру, который оставил текущий коммент, не отправляем уведомление о новом комментарии (т.е. о его же комментарии), т.к. он и так знает.
  206.             if ($subscriberEmail !== $this->emailCanonicalizer->canonicalize($currentUserEmail)) {
  207.                 $this->replaceVars($theme$body$comment$subscriber$pageUrl);
  208.                 $this->sendEmail($subscriberEmail$theme$body);
  209.             }
  210.         }
  211.     }
  212.     private function replaceVars(string &$themestring &$bodyCommentEntity $commentCommentablePageSubscriberEntity $subscriberstring $pageUrl)
  213.     {
  214.         $routeParameters = [
  215.             'token'   => md5($subscriber->getEmailCanonical() . self::UNSUB_SALT),
  216.             'email'   => $subscriber->getEmailCanonical(),
  217.             '_locale' => $comment->getLocale(),
  218.         ];
  219.         /** @var \FlexApp\Entity\ConsultantEntity $consultant */
  220.         if ($comment->getAuthorLogin()) {
  221.             $contacts $this->contactsProvider->getContacts($comment->getAuthorLogin(), $comment->getLocale());
  222.         } else {
  223.             $contacts $this->contactsProvider->getContacts();
  224.         }
  225.         $managerName $contacts->managerName;
  226.         $managerEmail $contacts->managerEmail;
  227.         $managerPhone $contacts->managerPhone;
  228.         $htmlLinkToPage "<a target='_blank' href='$pageUrl'>$pageUrl</a>";
  229.         $urlForUnsubscribe $this->router->generate('app_comment_unsubscribe_from_notifications'$routeParameters,
  230.             UrlGeneratorInterface::ABSOLUTE_URL);
  231.         $theme str_replace('%site%'$this->parametersProvider->getParameter('site'), $theme);
  232.         $body str_replace('%htmlLinkToPage%'$htmlLinkToPage$body);
  233.         $body str_replace('%commentText%'$comment->getBody(), $body);
  234.         $body str_replace('%urlForUnsubscribe%'$urlForUnsubscribe$body);
  235.         $body str_replace('%managerName%'$managerName$body);
  236.         $body str_replace('%managerEmail%'$managerEmail$body);
  237.         $body str_replace('%managerPhone%'$managerPhone$body);
  238.     }
  239.     private function sendNotificationToChat(string $tokenCommentEntity $comment): bool
  240.     {
  241.         try {
  242.             $pageUrl $this->sourceByCommentTypeDefiner->getSourceByCommentEntity($comment);
  243.         } catch (SourceByCommentTypeDefinerException $e) {
  244.             return false;
  245.         }
  246.         $word CommentEntity::QA === $comment->getCategory() ? 'qa' 'comment';
  247.         $pageUrl .= "#$word{$comment->getId()}";
  248.         $pageLink "<a target='_blank' href='$pageUrl'>$pageUrl</a>";
  249.         $message json_encode([
  250.             'key'        => 'new_comment_chat_notification',
  251.             'parameters' => [
  252.                 '%url%' => $pageLink,
  253.             ],
  254.         ], JSON_UNESCAPED_UNICODE);
  255.         $message Constants::NEED_TO_BE_TRANSLATED_MARKER $message;
  256.         return $this->systemChatNotificationService->addSystemMessageToChat($token$messagenullApp::getCurLocale(), App::getCurCountry(),
  257.             App::getCountryByIp());
  258.     }
  259. }