Files
speedBB/app/Http/Controllers/PostController.php
2026-01-14 00:15:56 +01:00

108 lines
3.2 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Post;
use App\Models\Thread;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class PostController extends Controller
{
public function index(Request $request): JsonResponse
{
$query = Post::query()->withoutTrashed()->with([
'user' => fn ($query) => $query->withCount('posts')->with('rank'),
]);
$threadParam = $request->query('thread');
if (is_string($threadParam)) {
$threadId = $this->parseIriId($threadParam);
if ($threadId !== null) {
$query->where('thread_id', $threadId);
}
}
$posts = $query
->oldest('created_at')
->get()
->map(fn (Post $post) => $this->serializePost($post));
return response()->json($posts);
}
public function store(Request $request): JsonResponse
{
$data = $request->validate([
'body' => ['required', 'string'],
'thread' => ['required', 'string'],
]);
$threadId = $this->parseIriId($data['thread']);
$thread = Thread::findOrFail($threadId);
$post = Post::create([
'thread_id' => $thread->id,
'user_id' => $request->user()?->id,
'body' => $data['body'],
]);
$post->loadMissing([
'user' => fn ($query) => $query->withCount('posts')->with('rank'),
]);
return response()->json($this->serializePost($post), 201);
}
public function destroy(Request $request, Post $post): JsonResponse
{
$post->deleted_by = $request->user()?->id;
$post->save();
$post->delete();
return response()->json(null, 204);
}
private function parseIriId(?string $value): ?int
{
if (!$value) {
return null;
}
if (preg_match('#/threads/(\d+)$#', $value, $matches)) {
return (int) $matches[1];
}
if (is_numeric($value)) {
return (int) $value;
}
return null;
}
private function serializePost(Post $post): array
{
return [
'id' => $post->id,
'body' => $post->body,
'thread' => "/api/threads/{$post->thread_id}",
'user_id' => $post->user_id,
'user_name' => $post->user?->name,
'user_avatar_url' => $post->user?->avatar_path
? Storage::url($post->user->avatar_path)
: null,
'user_posts_count' => $post->user?->posts_count,
'user_created_at' => $post->user?->created_at?->toIso8601String(),
'user_rank_name' => $post->user?->rank?->name,
'user_rank_badge_type' => $post->user?->rank?->badge_type,
'user_rank_badge_text' => $post->user?->rank?->badge_text,
'user_rank_badge_url' => $post->user?->rank?->badge_image_path
? Storage::url($post->user->rank->badge_image_path)
: null,
'created_at' => $post->created_at?->toIso8601String(),
'updated_at' => $post->updated_at?->toIso8601String(),
];
}
}