Topic.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. declare(strict_types=1);
  3. namespace ForkBB\Models\Pages;
  4. use ForkBB\Models\Page;
  5. use ForkBB\Models\Topic\Model as TopicModel;
  6. use function \ForkBB\__;
  7. class Topic extends Page
  8. {
  9. use PostFormTrait;
  10. /**
  11. * Переход к первому новому сообщению темы (или в конец)
  12. */
  13. public function viewNew(array $args): Page
  14. {
  15. return $this->view('new', $args);
  16. }
  17. /**
  18. * Переход к первому непрочитанному сообщению (или в конец)
  19. */
  20. public function viewUnread(array $args): Page
  21. {
  22. return $this->view('unread', $args);
  23. }
  24. /**
  25. * Переход к последнему сообщению темы
  26. */
  27. public function viewLast(array $args): Page
  28. {
  29. return $this->view('last', $args);
  30. }
  31. /**
  32. * Просмотр темы по номеру сообщения
  33. */
  34. public function viewPost(array $args): Page
  35. {
  36. return $this->view('post', $args);
  37. }
  38. /**
  39. * Просмотр темы по ее номеру
  40. */
  41. public function viewTopic(array $args): Page
  42. {
  43. return $this->view('topic', $args);
  44. }
  45. /**
  46. * Просмотр
  47. */
  48. protected function go(string $type, TopicModel $topic): Page
  49. {
  50. switch ($type) {
  51. case 'new':
  52. $pid = $topic->firstNew;
  53. break;
  54. case 'unread':
  55. $pid = $topic->firstUnread;
  56. break;
  57. case 'last':
  58. $pid = $topic->last_post_id;
  59. break;
  60. default:
  61. return $this->c->Message->message('Bad request');
  62. }
  63. return $this->c->Redirect->page('ViewPost', ['id' => $pid ?: $topic->last_post_id]);
  64. }
  65. /**
  66. * Подготовка данных для шаблона
  67. */
  68. protected function view(string $type, array $args): Page
  69. {
  70. if ('post' === $type) {
  71. $post = $this->c->posts->load((int) $args['id']);
  72. $topic = null === $post ? null : $post->parent;
  73. } else {
  74. $topic = $this->c->topics->load((int) $args['id']);
  75. }
  76. if (
  77. ! $topic instanceof TopicModel
  78. || ! $topic->last_post_id
  79. ) {
  80. return $this->c->Message->message('Bad request');
  81. }
  82. if ($topic->moved_to) {
  83. return $this->c->Redirect->page('Topic', ['id' => $topic->moved_to]);
  84. }
  85. switch ($type) {
  86. case 'topic':
  87. $topic->page = isset($args['page']) ? (int) $args['page'] : 1;
  88. break;
  89. case 'post':
  90. $topic->calcPage((int) $args['id']);
  91. break;
  92. default:
  93. return $this->go($type, $topic);
  94. }
  95. if (! $topic->hasPage()) {
  96. return $this->c->Message->message('Bad request');
  97. }
  98. if (! $posts = $topic->pageData()) {
  99. return $this->go('last', $topic);
  100. }
  101. $this->c->Lang->load('topic');
  102. $this->nameTpl = 'topic';
  103. $this->onlinePos = 'topic-' . $topic->id;
  104. $this->onlineDetail = true;
  105. $this->canonical = $this->c->Router->link(
  106. 'Topic',
  107. [
  108. 'id' => $topic->id,
  109. 'name' => $topic->censorSubject,
  110. 'page' => $topic->page
  111. ]
  112. );
  113. $this->model = $topic;
  114. $this->posts = $posts;
  115. $this->crumbs = $this->crumbs($topic);
  116. $this->online = $this->c->Online->calc($this)->info();
  117. $this->stats = null;
  118. if (
  119. $topic->canReply
  120. && '1' == $this->c->config->o_quickpost
  121. ) {
  122. $this->form = $this->messageForm(['id' => $topic->id], $topic, 'NewReply', false, false, true);
  123. }
  124. if (
  125. $this->user->isAdmin
  126. || $this->user->isModerator($topic)
  127. ) {
  128. $this->c->Lang->load('misc');
  129. $this->enableMod = true;
  130. $this->formMod = $this->formMod($topic);
  131. }
  132. if ($topic->showViews) {
  133. $topic->incViews();
  134. }
  135. $topic->updateVisits();
  136. if ($this->c->config->o_feed_type > 0) {
  137. $feedType = '2' == $this->c->config->o_feed_type ? 'atom' : 'rss';
  138. $this->pageHeader('feed', 'link', [
  139. 'rel' => 'alternate',
  140. 'type' => "application/{$feedType}+xml",
  141. 'href' => $this->c->Router->link('Feed', ['type' => $feedType, 'tid' => $topic->id]),
  142. ]);
  143. }
  144. return $this;
  145. }
  146. /**
  147. * Создает массив данных для формы модерации
  148. */
  149. protected function formMod(TopicModel $topic): array
  150. {
  151. $form = [
  152. 'id' => 'id-form-mod',
  153. 'action' => $this->c->Router->link('Moderate'),
  154. 'hidden' => [
  155. 'token' => $this->c->Csrf->create('Moderate'),
  156. 'forum' => $topic->parent->id,
  157. 'topic' => $topic->id,
  158. 'page' => $topic->page,
  159. 'ids' => [$topic->first_post_id => $topic->first_post_id],
  160. 'step' => 1,
  161. ],
  162. 'sets' => [],
  163. 'btns' => [],
  164. ];
  165. if ($topic->closed) {
  166. $form['btns']['open'] = [
  167. 'type' => 'submit',
  168. 'value' => __('Open topic'),
  169. ];
  170. } else {
  171. $form['btns']['close'] = [
  172. 'type' => 'submit',
  173. 'value' => __('Close topic'),
  174. ];
  175. }
  176. if ($topic->sticky) {
  177. $form['btns']['unstick'] = [
  178. 'type' => 'submit',
  179. 'value' => __('Unstick topic'),
  180. ];
  181. } else {
  182. $form['btns']['stick'] = [
  183. 'type' => 'submit',
  184. 'value' => __('Stick topic'),
  185. ];
  186. }
  187. $form['btns'] += [
  188. 'move' => [
  189. 'type' => 'submit',
  190. 'value' => __('Move topic'),
  191. ],
  192. 'delete' => [
  193. 'type' => 'submit',
  194. 'value' => __('Delete'),
  195. ],
  196. 'split' => [
  197. 'type' => 'submit',
  198. 'value' => __('Split'),
  199. ],
  200. ];
  201. return $form;
  202. }
  203. }