LoadTree.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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\Forum;
  10. use ForkBB\Models\Action;
  11. use ForkBB\Models\Forum\Forum;
  12. class LoadTree extends Action
  13. {
  14. /**
  15. * Загружает данные в модели для указанного раздела и всех его потомков
  16. */
  17. public function loadTree(int $rootId): ?Forum
  18. {
  19. $root = $this->manager->get($rootId);
  20. if (null === $root) {
  21. return null;
  22. }
  23. $list = [];
  24. if (! $root->ready) {
  25. $list[$rootId] = $root;
  26. }
  27. foreach ($root->descendants as $id => $descendant) {
  28. if (! $descendant->ready) {
  29. $list[$id] = $descendant;
  30. }
  31. }
  32. $this->loadData($list);
  33. if (! $this->c->user->isGuest) {
  34. $this->checkForNew($root->descendants);
  35. }
  36. return $root;
  37. }
  38. /**
  39. * Загружает данные из БД по списку разделов
  40. */
  41. protected function loadData(array $list): void
  42. {
  43. if (empty($list)) {
  44. return;
  45. }
  46. $vars = [
  47. ':uid' => $this->c->user->id,
  48. ':forums' => \array_keys($list),
  49. ];
  50. if ($this->c->user->isGuest) {
  51. $query = 'SELECT f.id, f.forum_desc, f.num_topics, f.sort_by, f.num_posts,
  52. f.last_post, f.last_post_id, f.last_poster, f.last_topic
  53. FROM ::forums AS f
  54. WHERE id IN (?ai:forums)';
  55. } elseif (1 === $this->c->config->b_forum_subscriptions) {
  56. $query = 'SELECT f.id, f.forum_desc, f.num_topics, f.sort_by, f.num_posts,
  57. f.last_post, f.last_post_id, f.last_poster, f.last_topic,
  58. mof.mf_mark_all_read, s.user_id AS is_subscribed
  59. FROM ::forums AS f
  60. LEFT JOIN ::forum_subscriptions AS s ON (s.user_id=?i:uid AND s.forum_id=f.id)
  61. LEFT JOIN ::mark_of_forum AS mof ON (mof.uid=?i:uid AND mof.fid=f.id)
  62. WHERE f.id IN (?ai:forums)';
  63. } else {
  64. $query = 'SELECT f.id, f.forum_desc, f.num_topics, f.sort_by, f.num_posts,
  65. f.last_post, f.last_post_id, f.last_poster, f.last_topic,
  66. mof.mf_mark_all_read
  67. FROM ::forums AS f
  68. LEFT JOIN ::mark_of_forum AS mof ON (mof.uid=?i:uid AND mof.fid=f.id)
  69. WHERE f.id IN (?ai:forums)';
  70. }
  71. $stmt = $this->c->DB->query($query, $vars);
  72. while ($cur = $stmt->fetch()) {
  73. $list[$cur['id']]->replAttrs($cur)->__ready = true;
  74. }
  75. }
  76. /**
  77. * Проверяет наличие новых сообщений в разделах по их списку
  78. */
  79. protected function checkForNew(array $list): void
  80. {
  81. if (
  82. empty($list)
  83. || $this->c->user->isGuest
  84. ) {
  85. return;
  86. }
  87. // предварительная проверка разделов
  88. $time = [];
  89. $max = \max((int) $this->c->user->last_visit, (int) $this->c->user->u_mark_all_read);
  90. foreach ($list as $forum) {
  91. $t = \max($max, (int) $forum->mf_mark_all_read);
  92. if ($forum->last_post > $t) {
  93. $time[$forum->id] = $t;
  94. }
  95. }
  96. if (empty($time)) {
  97. return;
  98. }
  99. // проверка по темам
  100. $vars = [
  101. ':uid' => $this->c->user->id,
  102. ':forums' => \array_keys($time),
  103. ':max' => $max,
  104. ];
  105. $query = 'SELECT t.forum_id, t.last_post
  106. FROM ::topics AS t
  107. LEFT JOIN ::mark_of_topic AS mot ON (mot.uid=?i:uid AND mot.tid=t.id)
  108. WHERE t.forum_id IN(?ai:forums)
  109. AND t.last_post>?i:max
  110. AND t.moved_to=0
  111. AND (mot.mt_last_visit IS NULL OR t.last_post>mot.mt_last_visit)';
  112. $stmt = $this->c->DB->query($query, $vars);
  113. while ($cur = $stmt->fetch()) {
  114. if ($cur['last_post'] > $time[$cur['forum_id']]) {
  115. $list[$cur['forum_id']]->__newMessages = true; //????
  116. }
  117. }
  118. }
  119. }