• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

marscoin / martianrepublic / 23902636081

02 Apr 2026 01:24PM UTC coverage: 11.256%. Remained the same
23902636081

push

github

Martian Congress
refactor: A5 — standardize model names to singular (Laravel convention)

Renamed:
- Ballots → Ballot
- Proposals → Proposal
- Threads → Thread
- Posts → Post

Updated all imports and references across 15 files.
Table names unchanged ($table property preserved).
146 tests passing, 0 PHPStan errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

6 of 38 new or added lines in 11 files covered. (15.79%)

664 of 5899 relevant lines covered (11.26%)

1.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/app/Http/Controllers/ForumApiController.php
1
<?php
2

3
namespace App\Http\Controllers;
4

5
use App\Models\Post;
6
use App\Models\Thread;
7
use Illuminate\Http\Request;
8
use Illuminate\Support\Facades\Auth;
9
use Illuminate\Support\Facades\DB;
10

11
class ForumApiController extends Controller
12
{
13
    public function getThreadsByCategory($categoryId)
×
14
    {
15
        $threads = $this->fetchThreads($categoryId);
×
16

17
        return response()->json(['threads' => $threads]);
×
18
    }
19

20
    public function getThreadComments($threadId)
×
21
    {
22
        // Assume $threadId is passed correctly to the function
23
        $comments = $this->fetchCommentsByThread($threadId);
×
24

25
        return response()->json(['comments' => $comments]);
×
26
    }
27

28
    public function getAllCategoriesWithThreads()
×
29
    {
30
        $userId = Auth::id();
×
31

32
        $categories = DB::table('forum_categories')->get();
×
33

34
        // Fetch all threads in a single query instead of N+1
35
        $threads = DB::table('forum_threads')
×
36
            ->leftJoin('users', 'forum_threads.author_id', '=', 'users.id')
×
37
            ->leftJoin('profile', 'users.id', '=', 'profile.userid')
×
38
            ->leftJoin('user_blocks as ub', function ($join) use ($userId) {
×
39
                $join->on('forum_threads.author_id', '=', 'ub.blocked_user_id')
×
40
                    ->where('ub.user_id', '=', $userId);
×
41
            })
×
42
            ->select(
×
43
                'forum_threads.id',
×
44
                'forum_threads.category_id',
×
45
                'forum_threads.title',
×
46
                'forum_threads.created_at',
×
47
                'forum_threads.reply_count',
×
48
                'users.fullname as author_name',
×
49
                DB::raw('IF(ub.blocked_user_id IS NOT NULL, true, false) as is_blocked')
×
50
            )
×
51
            ->orderBy('forum_threads.created_at', 'desc')
×
52
            ->get()
×
53
            ->groupBy('category_id');
×
54

55
        foreach ($categories as $category) {
×
56
            $category->threads = $threads->get($category->id, collect());
×
57
        }
58

59
        return response()->json(['categories' => $categories]);
×
60
    }
61

62
    public function createThread(Request $request)
×
63
    {
64
        $request->validate([
×
65
            'category_id' => 'required|exists:forum_categories,id',
×
66
            'title' => 'required|string|max:255',
×
67
            'content' => 'required|string',
×
68
        ]);
×
69

NEW
70
        $thread = new Thread;
×
71
        $thread->category_id = $request->category_id;
×
72
        $thread->author_id = Auth::id();
×
73
        $thread->title = $request->title;
×
74
        $thread->save();
×
75

NEW
76
        $post = new Post;
×
77
        $post->thread_id = $thread->id;
×
78
        $post->author_id = Auth::id();
×
79
        $post->content = $request->content;
×
80
        $post->save();
×
81

82
        $thread->first_post_id = $post->id;
×
83
        $thread->last_post_id = $post->id;
×
84
        $thread->reply_count = 0;
×
85
        $thread->save();
×
86

87
        return response()->json([
×
88
            'message' => 'Thread created successfully',
×
89
            'thread_id' => $thread->id,
×
90
            'post_id' => $post->id,
×
91
        ], 201);
×
92
    }
93

94
    public function createComment(Request $request, $threadId)
×
95
    {
96
        $request->validate([
×
97
            'content' => 'required|string',
×
98
            'post_id' => 'nullable|exists:forum_posts,id',
×
99
        ]);
×
100

NEW
101
        $thread = Thread::findOrFail($threadId);
×
102

NEW
103
        $post = new Post;
×
104
        $post->thread_id = $threadId;
×
105
        $post->author_id = Auth::id();
×
106
        $post->content = $request->content;
×
107
        $post->post_id = $request->post_id; // This will be null for top-level comments
×
108
        $post->save();
×
109

110
        $thread->last_post_id = $post->id;
×
111
        $thread->reply_count += 1;
×
112
        $thread->save();
×
113

114
        return response()->json([
×
115
            'message' => 'Comment created successfully',
×
116
            'post_id' => $post->id,
×
117
        ], 201);
×
118
    }
119

120
    private function fetchThreads($categoryId)
×
121
    {
122
        $userId = Auth::id();
×
123

124
        $threads = DB::table('forum_threads')
×
125
            ->where('forum_threads.category_id', $categoryId)
×
126
            ->leftJoin('users', 'forum_threads.author_id', '=', 'users.id')
×
127
            ->leftJoin('profile', 'users.id', '=', 'profile.userid')
×
128
            ->leftJoin('user_blocks as ub', function ($join) use ($userId) {
×
129
                $join->on('forum_threads.author_id', '=', 'ub.blocked_user_id')
×
130
                    ->where('ub.user_id', '=', $userId);
×
131
            })
×
132
            ->select(
×
133
                'forum_threads.id',
×
134
                'forum_threads.title',
×
135
                'forum_threads.created_at',
×
136
                'forum_threads.reply_count',
×
137
                'users.fullname as author_name',
×
138
                DB::raw('IF(ub.blocked_user_id IS NOT NULL, true, false) as is_blocked')
×
139
            )
×
140
            ->orderBy('forum_threads.created_at', 'desc')
×
141
            ->get();
×
142

143
        return $threads;
×
144
    }
145

146
    private function fetchCommentsByThread($threadId)
×
147
    {
148
        $userId = Auth::id();
×
149

150
        $query = '
×
151
            WITH RECURSIVE CommentTree AS (
152
                SELECT
153
                    p.id,
154
                    p.thread_id,
155
                    p.author_id,
156
                    p.content,
157
                    p.post_id as pid,
158
                    p.created_at,
159
                    CHAR_LENGTH(p.content) as char_length_sum
160
                FROM
161
                    forum_posts p
162
                WHERE
163
                    p.thread_id = ? AND p.post_id IS NULL
164

165
                UNION ALL
166

167
                SELECT
168
                    p.id,
169
                    p.thread_id,
170
                    p.author_id,
171
                    p.content,
172
                    p.post_id,
173
                    p.created_at,
174
                    ct.char_length_sum + CHAR_LENGTH(p.content)
175
                FROM
176
                    forum_posts p
177
                INNER JOIN
178
                    CommentTree ct ON p.post_id = ct.id
179
            )
180
            SELECT
181
                ct.id,
182
                ct.thread_id,
183
                ct.author_id,
184
                u.fullname,
185
                ct.content,
186
                ct.created_at,
187
                ct.pid,
188
                CHAR_LENGTH(ct.content) as char_length_sum,
189
                IF(ub.blocked_user_id IS NOT NULL, true, false) as is_blocked
190
            FROM
191
                CommentTree ct
192
            LEFT JOIN users u ON ct.author_id = u.id
193
            LEFT JOIN profile pr ON ct.author_id = pr.userid
194
            LEFT JOIN user_blocks ub ON ub.blocked_user_id = ct.author_id AND ub.user_id = ?
195
            ORDER BY
196
                ct.pid ASC,
197
                ct.created_at ASC;
198
        ';
×
199

200
        $comments = DB::select($query, [$threadId, $userId]);
×
201
        $commentsCollection = collect($comments);
×
202

203
        return response()->json(['comments' => $commentsCollection]);
×
204
    }
205
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc