1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Http\Controllers\Forum;
7
8use App\Models\Forum\Forum;
9use App\Models\Forum\Post;
10use App\Models\Forum\Topic;
11use App\Models\Forum\TopicTrack;
12use App\Transformers\Forum\ForumCoverTransformer;
13use Auth;
14
15class ForumsController extends Controller
16{
17 public function __construct()
18 {
19 parent::__construct();
20 }
21
22 public function index()
23 {
24 $forums = Forum
25 ::where('parent_id', 0)
26 ->with('subforums.subforums')
27 ->orderBy('left_id')
28 ->get();
29
30 $lastTopics = Forum::lastTopics();
31
32 $forums = $forums->filter(function ($forum) {
33 return priv_check('ForumView', $forum)->can();
34 });
35
36 return ext_view('forum.forums.index', compact('forums', 'lastTopics'));
37 }
38
39 public function markAsRead()
40 {
41 if (Auth::check()) {
42 $forumId = get_int(request('forum_id'));
43 if ($forumId === null) {
44 Forum::markAllAsRead(Auth::user());
45 } else {
46 $recursive = get_bool(request('recursive')) ?? false;
47 $forum = Forum::findOrFail($forumId);
48 priv_check('ForumView', $forum)->ensureCan();
49 $forum->markAsRead(Auth::user(), $recursive);
50 }
51 }
52
53 return ext_view('layout.ujs-reload', [], 'js');
54 }
55
56 public function show($id)
57 {
58 $params = get_params(request()->all(), null, [
59 'sort',
60 'with_replies',
61 ]);
62
63 $user = auth()->user();
64
65 $forum = Forum::with('subforums.subforums')->findOrFail($id);
66 $lastTopics = Forum::lastTopics($forum);
67
68 $sort = $params['sort'] ?? Topic::DEFAULT_SORT;
69 $withReplies = $params['with_replies'] ?? null;
70
71 priv_check('ForumView', $forum)->ensureCan();
72
73 $cover = json_item(
74 $forum->cover()->firstOrNew([]),
75 new ForumCoverTransformer()
76 );
77
78 $showDeleted = priv_check('ForumModerate', $forum)->can();
79
80 $pinnedTopics = $forum->topics()
81 ->with('forum')
82 ->pinned()
83 ->showDeleted($showDeleted)
84 ->orderBy('topic_type', 'desc')
85 ->recent()
86 ->get();
87 $topics = $forum->topics()
88 ->with('forum')
89 ->normal()
90 ->showDeleted($showDeleted)
91 ->recent(compact('sort', 'withReplies'))
92 ->paginate();
93
94 $allTopics = array_merge($pinnedTopics->all(), $topics->all());
95 $topicReadStatus = TopicTrack::readStatus($user, $allTopics);
96 $topicReplyStatus = $user === null
97 ? []
98 : Post
99 ::where('poster_id', $user->getKey())
100 ->whereIn('topic_id', array_pluck($allTopics, 'topic_id'))
101 ->distinct('topic_id')
102 ->select('topic_id')
103 ->get()
104 ->keyBy('topic_id');
105
106 $noindex = !$forum->enable_indexing;
107
108 set_opengraph($forum);
109
110 return ext_view('forum.forums.show', compact(
111 'cover',
112 'forum',
113 'lastTopics',
114 'noindex',
115 'pinnedTopics',
116 'sort',
117 'topicReadStatus',
118 'topicReplyStatus',
119 'topics'
120 ));
121 }
122}