Просмотр файла app/Http/Controllers/Forum/ForumController.php

Размер файла: 9.39Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Http\Controllers\Forum;
  6.  
  7. use App\Classes\Validator;
  8. use App\Http\Controllers\Controller;
  9. use App\Models\Flood;
  10. use App\Models\Forum;
  11. use App\Models\Post;
  12. use App\Models\Topic;
  13. use App\Models\Vote;
  14. use App\Models\VoteAnswer;
  15. use Illuminate\Http\RedirectResponse;
  16. use Illuminate\Support\Facades\DB;
  17. use Illuminate\Database\Eloquent\Builder;
  18. use Illuminate\Database\Query\JoinClause;
  19. use Illuminate\Http\Request;
  20. use Illuminate\View\View;
  21.  
  22. class ForumController extends Controller
  23. {
  24. /**
  25. * Главная страница
  26. *
  27. * @return View
  28. */
  29. public function index(): View
  30. {
  31. $forums = Forum::query()
  32. ->where('parent_id', 0)
  33. ->with('lastTopic.lastPost.user')
  34. ->with('children')
  35. ->orderBy('sort')
  36. ->get();
  37.  
  38. if ($forums->isEmpty()) {
  39. abort(200, __('forums.empty_forums'));
  40. }
  41.  
  42. return view('forums/index', compact('forums'));
  43. }
  44.  
  45. /**
  46. * Страница списка тем
  47. *
  48. * @param int $id
  49. *
  50. * @return View
  51. */
  52. public function forum(int $id): View
  53. {
  54. /** @var Forum $forum */
  55. $forum = Forum::query()->with('parent', 'children.lastTopic.lastPost.user')->find($id);
  56.  
  57. if (! $forum) {
  58. abort(404, __('forums.forum_not_exist'));
  59. }
  60.  
  61. $user = getUser();
  62.  
  63. $topics = Topic::query()
  64. ->where('forum_id', $forum->id)
  65. ->when($user, static function (Builder $query) use ($user) {
  66. $query->select('topics.*', 'bookmarks.count_posts as bookmark_posts')
  67. ->leftJoin('bookmarks', static function (JoinClause $join) use ($user) {
  68. $join->on('topics.id', 'bookmarks.topic_id')
  69. ->where('bookmarks.user_id', $user->id);
  70. });
  71. })
  72. ->orderByDesc('locked')
  73. ->orderByDesc('updated_at')
  74. ->with('lastPost.user')
  75. ->paginate(setting('forumtem'));
  76.  
  77. return view('forums/forum', compact('forum', 'topics'));
  78. }
  79.  
  80. /**
  81. * Создание новой темы
  82. *
  83. * @param Request $request
  84. * @param Validator $validator
  85. * @param Flood $flood
  86. *
  87. * @return View|RedirectResponse
  88. */
  89. public function create(Request $request, Validator $validator, Flood $flood)
  90. {
  91. $fid = int($request->input('fid'));
  92.  
  93. $forums = Forum::query()
  94. ->where('parent_id', 0)
  95. ->with('children')
  96. ->orderBy('sort')
  97. ->get();
  98.  
  99. if ($forums->isEmpty()) {
  100. abort(200, __('forums.empty_forums'));
  101. }
  102.  
  103. if (! $user = getUser()) {
  104. abort(403);
  105. }
  106.  
  107. if ($request->isMethod('post')) {
  108. $title = $request->input('title');
  109. $msg = $request->input('msg');
  110. $vote = empty($request->input('vote')) ? 0 : 1;
  111. $question = $request->input('question');
  112. $answers = (array) $request->input('answers');
  113.  
  114. /** @var Forum $forum */
  115. $forum = Forum::query()->find($fid);
  116.  
  117. $validator->equal($request->input('_token'), csrf_token(), __('validator.token'))
  118. ->notEmpty($forum, ['fid' => 'Форума для новой темы не существует!'])
  119. ->false($flood->isFlood(), ['msg' => __('validator.flood', ['sec' => $flood->getPeriod()])])
  120. ->length($title, 3, 50, ['title' => __('validator.text')])
  121. ->length($msg, 5, setting('forumtextlength'), ['msg' => __('validator.text')]);
  122.  
  123. if ($forum) {
  124. $validator->empty($forum->closed, ['fid' => __('forums.forum_closed')]);
  125. }
  126.  
  127. if ($vote) {
  128. $validator->length($question, 5, 100, ['question' => __('validator.text')]);
  129. $answers = array_unique(array_diff($answers, ['']));
  130.  
  131. foreach ($answers as $answer) {
  132. if (utfStrlen($answer) > 50) {
  133. $validator->addError(['answers' => __('votes.answer_wrong_length')]);
  134. break;
  135. }
  136. }
  137.  
  138. $validator->between(count($answers), 2, 10, ['answers' => __('votes.answer_not_enough')]);
  139. }
  140.  
  141. /* TODO: Сделать проверку поиска похожей темы */
  142.  
  143. if ($validator->isValid()) {
  144. $title = antimat($title);
  145. $msg = antimat($msg);
  146.  
  147. $user->increment('allforum');
  148. $user->increment('point');
  149. $user->increment('money', 5);
  150.  
  151. /** @var Topic $topic */
  152. $topic = Topic::query()->create([
  153. 'forum_id' => $forum->id,
  154. 'title' => $title,
  155. 'user_id' => getUser('id'),
  156. 'count_posts' => 1,
  157. 'created_at' => SITETIME,
  158. 'updated_at' => SITETIME,
  159. ]);
  160.  
  161. /** @var Post $post */
  162. $post = Post::query()->create([
  163. 'topic_id' => $topic->id,
  164. 'user_id' => getUser('id'),
  165. 'text' => $msg,
  166. 'created_at' => SITETIME,
  167. 'ip' => getIp(),
  168. 'brow' => getBrowser(),
  169. ]);
  170.  
  171. Topic::query()->where('id', $topic->id)->update(['last_post_id' => $post->id]);
  172.  
  173. $forum->update([
  174. 'count_topics' => DB::raw('count_topics + 1'),
  175. 'count_posts' => DB::raw('count_posts + 1'),
  176. 'last_topic_id' => $topic->id,
  177. ]);
  178.  
  179. // Обновление родительского форума
  180. if ($forum->parent->id) {
  181. $forum->parent->update([
  182. 'last_topic_id' => $topic->id
  183. ]);
  184. }
  185.  
  186. // Создание голосования
  187. if ($vote) {
  188. /** @var Vote $vote */
  189. $vote = Vote::query()->create([
  190. 'title' => $question,
  191. 'topic_id' => $topic->id,
  192. 'created_at' => SITETIME,
  193. ]);
  194.  
  195. $prepareAnswers = [];
  196. foreach ($answers as $answer) {
  197. $prepareAnswers[] = [
  198. 'vote_id' => $vote->id,
  199. 'answer' => $answer
  200. ];
  201. }
  202.  
  203. VoteAnswer::query()->insert($prepareAnswers);
  204. }
  205.  
  206. clearCache(['statForums', 'recentTopics']);
  207. $flood->saveState();
  208.  
  209. setFlash('success', __('forums.topic_success_created'));
  210.  
  211. return redirect('topics/'.$topic->id);
  212. }
  213.  
  214. setInput($request->all());
  215. setFlash('danger', $validator->getErrors());
  216. }
  217.  
  218. return view('forums/topic_create', compact('forums', 'fid'));
  219. }
  220.  
  221. /**
  222. * RSS всех топиков
  223. *
  224. * @return View
  225. */
  226. public function rss(): View
  227. {
  228. $topics = Topic::query()
  229. ->where('closed', 0)
  230. ->with('lastPost.user')
  231. ->orderByDesc('updated_at')
  232. ->limit(15)
  233. ->get();
  234.  
  235. if ($topics->isEmpty()) {
  236. abort(200, __('forums.topics_not_created'));
  237. }
  238.  
  239. return view('forums/rss', compact('topics'));
  240. }
  241.  
  242. /**
  243. * RSS постов
  244. *
  245. * @param int $id
  246. *
  247. * @return View
  248. */
  249. public function rssPosts(int $id): View
  250. {
  251. /** @var Topic $topic */
  252. $topic = Topic::query()->find($id);
  253.  
  254. if (! $topic) {
  255. abort(404, __('forums.topic_not_exist'));
  256. }
  257.  
  258. $posts = Post::query()
  259. ->where('topic_id', $topic->id)
  260. ->orderByDesc('created_at')
  261. ->with('user')
  262. ->limit(15)
  263. ->get();
  264.  
  265. return view('forums/rss_posts', compact('topic', 'posts'));
  266. }
  267.  
  268. /**
  269. * Последние темы
  270. *
  271. * @return View
  272. */
  273. public function topTopics(): View
  274. {
  275. $topics = Topic::query()
  276. ->orderByDesc('count_posts')
  277. ->orderByDesc('updated_at')
  278. ->with('forum', 'user', 'lastPost.user')
  279. ->limit(100)
  280. ->get()
  281. ->all();
  282.  
  283. $topics = paginate($topics, setting('forumtem'));
  284.  
  285. return view('forums/top', compact('topics'));
  286. }
  287.  
  288. /**
  289. * Последние сообщения
  290. *
  291. * @param Request $request
  292. *
  293. * @return View
  294. */
  295. public function topPosts(Request $request): View
  296. {
  297. $period = int($request->input('period'));
  298.  
  299. $posts = Post::query()
  300. ->when($period, static function (Builder $query) use ($period) {
  301. return $query->where('created_at', '>', strtotime('-' . $period . ' day', SITETIME));
  302. })
  303. ->orderByDesc('rating')
  304. ->orderByDesc('created_at')
  305. ->with('topic', 'user')
  306. ->limit(100)
  307. ->get()
  308. ->all();
  309.  
  310. $posts = paginate($posts, setting('forumpost'), ['period' => $period]);
  311.  
  312. return view('forums/top_posts', compact('posts', 'period'));
  313. }
  314. }