Send.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. /**
  3. * This file is part of the ForkBB <https://github.com/forkbb>.
  4. *
  5. * @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
  6. * @license The MIT License (MIT)
  7. */
  8. declare(strict_types=1);
  9. namespace ForkBB\Models\Subscription;
  10. use ForkBB\Models\Method;
  11. use ForkBB\Models\Forum\Forum;
  12. use ForkBB\Models\Post\Post;
  13. use ForkBB\Models\Topic\Topic;
  14. use ForkBB\Core\Exceptions\MailException;
  15. use function \ForkBB\__;
  16. class Send extends Method
  17. {
  18. /**
  19. * Рассылает письма по подпискам для новых тем/ответов
  20. */
  21. public function send(Post $post, Topic $topic = null)
  22. {
  23. try {
  24. if (null === $topic) {
  25. $newTopic = false;
  26. $tplNameFull = 'new_reply_full.tpl';
  27. $tplNameShort = 'new_reply.tpl';
  28. $topic = $post->parent;
  29. $forum = $topic->parent;
  30. $vars = [
  31. ':uid' => $this->c->user->id,
  32. ':tid' => $topic->id,
  33. ':prev' => $this->c->posts->previousPost($post, false),
  34. ];
  35. $query = 'SELECT u.id, u.username, u.group_id, u.email, u.email_confirmed, u.notify_with_post, u.language
  36. FROM ::users AS u
  37. INNER JOIN ::topic_subscriptions AS s ON u.id=s.user_id
  38. LEFT JOIN ::online AS o ON u.id=o.user_id
  39. WHERE s.topic_id=?i:tid AND u.id!=?i:uid AND COALESCE(o.logged, u.last_visit)>?i:prev';
  40. } else {
  41. $newTopic = true;
  42. $tplNameFull = 'new_topic_full.tpl';
  43. $tplNameShort = 'new_topic.tpl';
  44. $forum = $topic->parent;
  45. $vars = [
  46. ':uid' => $this->c->user->id,
  47. ':fid' => $forum->id,
  48. ];
  49. $query = 'SELECT u.id, u.username, u.group_id, u.email, u.email_confirmed, u.notify_with_post, u.language
  50. FROM ::users AS u
  51. INNER JOIN ::forum_subscriptions AS s ON u.id=s.user_id
  52. WHERE s.forum_id=?i:fid AND u.id!=?i:uid';
  53. }
  54. $data = [];
  55. $grPerm = [
  56. $this->c->user->group_id => true,
  57. ];
  58. $stmt = $this->c->DB->query($query, $vars);
  59. while ($row = $stmt->fetch()) {
  60. $user = $this->c->users->create($row);
  61. if (
  62. 1 !== $user->email_confirmed
  63. || $this->c->bans->banFromName($user->username) > 0
  64. || $this->c->Online->isOnline($user)
  65. ) {
  66. continue;
  67. }
  68. if (! isset($grPerm[$user->group_id])) {
  69. $group = $this->c->groups->get($user->group_id);
  70. $grPerm[$user->group_id] = $this->c->ForumManager->init($group)->get($forum->id) instanceof Forum;
  71. }
  72. if (! $grPerm[$user->group_id]) {
  73. continue;
  74. }
  75. if (empty($data[$user->language])) {
  76. $data[$user->language] = [
  77. 'short' => [],
  78. 'full' => [],
  79. ];
  80. }
  81. $type = 1 === $user->notify_with_post ? 'full' : 'short';
  82. $data[$user->language][$type][$user->email] = $user->username;
  83. }
  84. foreach ($data as $lang => $dataLang) {
  85. $this->c->Lang->load('common', $lang);
  86. if ($newTopic) {
  87. $tplData = [
  88. 'forumName' => $forum->name,
  89. 'poster' => $topic->poster,
  90. 'topicSubject' => $topic->name,
  91. 'topicLink' => $topic->link,
  92. 'unsubscribeLink' => $forum->link,
  93. 'button' => __('Unsubscribe'),
  94. 'fMailer' => __(['Mailer', $this->c->config->o_board_title]),
  95. ];
  96. } else {
  97. $tplData = [
  98. 'forumName' => $forum->name,
  99. 'replier' => $post->poster,
  100. 'topicSubject' => $topic->name,
  101. 'postLink' => $post->link,
  102. 'unsubscribeLink' => $topic->link,
  103. 'button' => __('Unsubscribe'),
  104. 'fMailer' => __(['Mailer', $this->c->config->o_board_title]),
  105. ];
  106. }
  107. if (! empty($dataLang['short'])) {
  108. $this->c->Mail
  109. ->reset()
  110. ->setMaxRecipients((int) $this->c->config->i_email_max_recipients)
  111. ->setFolder($this->c->DIR_LANG)
  112. ->setLanguage($lang)
  113. ->setFrom($this->c->config->o_webmaster_email, $tplData['fMailer'])
  114. ->setTpl($tplNameShort, $tplData);
  115. foreach ($dataLang['short'] as $email => $name) {
  116. $this->c->Mail->addTo($email, $name);
  117. }
  118. $this->c->Mail->send();
  119. }
  120. if (! empty($dataLang['full'])) {
  121. // $message = $this->c->Parser->prepare($post->message); // парсер хранит сообщение
  122. $tplData['message'] = $this->c->Parser->parseMessage(null, (bool) $post->hide_smilies);
  123. $this->c->Mail
  124. ->reset()
  125. ->setMaxRecipients((int) $this->c->config->i_email_max_recipients)
  126. ->setFolder($this->c->DIR_LANG)
  127. ->setLanguage($lang)
  128. ->setFrom($this->c->config->o_webmaster_email, $tplData['fMailer'])
  129. ->setTpl($tplNameFull, $tplData);
  130. foreach ($dataLang['full'] as $email => $name) {
  131. $this->c->Mail->addTo($email, $name);
  132. }
  133. $this->c->Mail->send();
  134. }
  135. }
  136. $this->c->Lang->load('common', $this->c->user->language);
  137. } catch (MailException $e) {
  138. $this->c->Log->error('Subscription: MailException', [
  139. 'exception' => $e,
  140. 'headers' => false,
  141. ]);
  142. }
  143. }
  144. }