From d7081be140b8a00b05be5060b2c8085a3c26554f Mon Sep 17 00:00:00 2001 From: iam-subho <55249273+iam-subho@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:44:54 +0530 Subject: [PATCH 1/5] Prevent users from creating more than 5 forum threads per day #1161 --- .../Controllers/Forum/ThreadsController.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/Http/Controllers/Forum/ThreadsController.php b/app/Http/Controllers/Forum/ThreadsController.php index ed8988a77..3eb13d6f1 100644 --- a/app/Http/Controllers/Forum/ThreadsController.php +++ b/app/Http/Controllers/Forum/ThreadsController.php @@ -91,6 +91,25 @@ public function create(): View public function store(ThreadRequest $request): RedirectResponse { + $userId = Auth::id(); // Get the authenticated user's ID + $midnight = now()->endOfDay(); + $remainingSeconds = $midnight->diffInSeconds(now()); + + // Count the threads posted by the user today + $cacheKey = "user_threads_count_{$userId}"; + $threadCount = Cache::remember($cacheKey, $remainingSeconds, function () use ($userId) { + return Thread::where('author_id', $userId) + ->where('created_at', '>=', now()->startOfDay()) + ->count(); + }); + + // Check if the user has reached the limit + if ($threadCount >= 1) { + $this->error('You can only post a maximum of 5 threads per day.'); + return redirect()->route('forum'); + } + + $this->dispatchSync(CreateThread::fromRequest($request, $uuid = Str::uuid())); $thread = Thread::findByUuidOrFail($uuid); From e3db4bd3d4e13a005ece94d6180fa48d77d42511 Mon Sep 17 00:00:00 2001 From: iam-subho <55249273+iam-subho@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:44:54 +0530 Subject: [PATCH 2/5] Prevent users from creating more than 5 forum threads per day #1161 --- .env.example | 2 ++ .../Controllers/Forum/ThreadsController.php | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/.env.example b/.env.example index 0581c42f0..3e5a17d3d 100644 --- a/.env.example +++ b/.env.example @@ -53,3 +53,5 @@ LOG_STACK=single SESSION_ENCRYPT=false SESSION_PATH=/ SESSION_DOMAIN=null + +APP_MAX_THREAD_COUNT = 5 diff --git a/app/Http/Controllers/Forum/ThreadsController.php b/app/Http/Controllers/Forum/ThreadsController.php index ed8988a77..51d2bfdd1 100644 --- a/app/Http/Controllers/Forum/ThreadsController.php +++ b/app/Http/Controllers/Forum/ThreadsController.php @@ -91,6 +91,25 @@ public function create(): View public function store(ThreadRequest $request): RedirectResponse { + $userId = Auth::id(); // Get the authenticated user's ID + $midnight = now()->endOfDay(); + $remainingSeconds = $midnight->diffInSeconds(now()); + + // Count the threads posted by the user today + $cacheKey = "user_threads_count_{$userId}"; + $threadCount = Cache::remember($cacheKey, $remainingSeconds, function () use ($userId) { + return Thread::where('author_id', $userId) + ->where('created_at', '>=', now()->startOfDay()) + ->count(); + }); + + // Check if the user has reached the limit + if ($threadCount >= getenv('APP_MAX_THREAD_COUNT')) { + $this->error('You can only post a maximum of 5 threads per day.'); + return redirect()->route('forum'); + } + + $this->dispatchSync(CreateThread::fromRequest($request, $uuid = Str::uuid())); $thread = Thread::findByUuidOrFail($uuid); From 77cb89fe4bc434da021be2b4390df748d923bd20 Mon Sep 17 00:00:00 2001 From: iam-subho <55249273+iam-subho@users.noreply.github.com> Date: Wed, 30 Oct 2024 09:06:33 +0530 Subject: [PATCH 3/5] Prevent users from creating more than 5 forum threads per day #1161 --- .../Controllers/Forum/ThreadsController.php | 23 ++++++++----------- app/Models/User.php | 9 ++++++++ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/Forum/ThreadsController.php b/app/Http/Controllers/Forum/ThreadsController.php index 51d2bfdd1..ef3ce84ac 100644 --- a/app/Http/Controllers/Forum/ThreadsController.php +++ b/app/Http/Controllers/Forum/ThreadsController.php @@ -81,30 +81,27 @@ public function show(Thread $thread) return view('forum.threads.show', compact('thread', 'moderators')); } - public function create(): View + public function create() { $tags = Tag::all(); $selectedTags = old('tags') ?: []; + $threadCount = Auth::user()->threadsCountToday(); + if ($threadCount >= 5) { + $this->error('You can only post a maximum of 5 threads per day.'); + return redirect()->route('forum'); + } + return view('forum.threads.create', ['tags' => $tags, 'selectedTags' => $selectedTags]); } public function store(ThreadRequest $request): RedirectResponse { - $userId = Auth::id(); // Get the authenticated user's ID - $midnight = now()->endOfDay(); - $remainingSeconds = $midnight->diffInSeconds(now()); - - // Count the threads posted by the user today - $cacheKey = "user_threads_count_{$userId}"; - $threadCount = Cache::remember($cacheKey, $remainingSeconds, function () use ($userId) { - return Thread::where('author_id', $userId) - ->where('created_at', '>=', now()->startOfDay()) - ->count(); - }); + + $threadCount = Auth::user()->threadsCountToday(); // Check if the user has reached the limit - if ($threadCount >= getenv('APP_MAX_THREAD_COUNT')) { + if ($threadCount >= 5) { $this->error('You can only post a maximum of 5 threads per day.'); return redirect()->route('forum'); } diff --git a/app/Models/User.php b/app/Models/User.php index 69aba8f99..b64c2c50a 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -5,6 +5,7 @@ use App\Concerns\HasTimestamps; use App\Concerns\PreparesSearch; use App\Enums\NotificationType; +use Carbon\Carbon; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -196,6 +197,14 @@ public function countThreads(): int return $this->threadsRelation()->count(); } + + public function threadsCountToday(): int + { + return $this->threadsRelation() + ->whereDate('created_at', Carbon::today()) + ->count(); + } + /** * @return \Illuminate\Database\Eloquent\Collection */ From 648aa4262fc100d7276bbb9d9903eab31daeac85 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 1 Nov 2024 11:19:27 +0100 Subject: [PATCH 4/5] wip --- .env.example | 2 -- .../Controllers/Forum/ThreadsController.php | 18 +++++++----------- app/Models/User.php | 12 +++++++++--- tests/Feature/ForumTest.php | 16 ++++++++++++++++ 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/.env.example b/.env.example index 3e5a17d3d..0581c42f0 100644 --- a/.env.example +++ b/.env.example @@ -53,5 +53,3 @@ LOG_STACK=single SESSION_ENCRYPT=false SESSION_PATH=/ SESSION_DOMAIN=null - -APP_MAX_THREAD_COUNT = 5 diff --git a/app/Http/Controllers/Forum/ThreadsController.php b/app/Http/Controllers/Forum/ThreadsController.php index ef3ce84ac..2552585a2 100644 --- a/app/Http/Controllers/Forum/ThreadsController.php +++ b/app/Http/Controllers/Forum/ThreadsController.php @@ -83,30 +83,26 @@ public function show(Thread $thread) public function create() { - $tags = Tag::all(); - $selectedTags = old('tags') ?: []; - - $threadCount = Auth::user()->threadsCountToday(); - if ($threadCount >= 5) { + if (Auth::user()->hasTooManyThreadsToday()) { $this->error('You can only post a maximum of 5 threads per day.'); + return redirect()->route('forum'); } + $tags = Tag::all(); + $selectedTags = old('tags') ?: []; + return view('forum.threads.create', ['tags' => $tags, 'selectedTags' => $selectedTags]); } public function store(ThreadRequest $request): RedirectResponse { - - $threadCount = Auth::user()->threadsCountToday(); - - // Check if the user has reached the limit - if ($threadCount >= 5) { + if (Auth::user()->hasTooManyThreadsToday()) { $this->error('You can only post a maximum of 5 threads per day.'); + return redirect()->route('forum'); } - $this->dispatchSync(CreateThread::fromRequest($request, $uuid = Str::uuid())); $thread = Thread::findByUuidOrFail($uuid); diff --git a/app/Models/User.php b/app/Models/User.php index b64c2c50a..3515d8420 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -197,14 +197,20 @@ public function countThreads(): int return $this->threadsRelation()->count(); } - - public function threadsCountToday(): int + public function countThreadsFromToday(): int { + $today = Carbon::today(); + return $this->threadsRelation() - ->whereDate('created_at', Carbon::today()) + ->whereBetween('created_at', [$today, $today->copy()->endOfDay()]) ->count(); } + public function hasTooManyThreadsToday(): bool + { + return $this->countThreadsFromToday() >= 5; + } + /** * @return \Illuminate\Database\Eloquent\Collection */ diff --git a/tests/Feature/ForumTest.php b/tests/Feature/ForumTest.php index b85b8672c..719c5c335 100644 --- a/tests/Feature/ForumTest.php +++ b/tests/Feature/ForumTest.php @@ -83,6 +83,22 @@ ->assertSessionHas('success', 'Thread successfully created!'); }); +test('users cannot create more than 5 threads per day', function () { + $tag = Tag::factory()->create(['name' => 'Test Tag']); + + $user = $this->login(); + + Thread::factory()->count(5)->create(['author_id' => $user->id(), 'created_at' => now()]); + + $this->post('/forum/create-thread', [ + 'subject' => 'How to work with Eloquent?', + 'body' => 'This text explains how to work with Eloquent.', + 'tags' => [$tag->id()], + ]) + ->assertRedirect('/forum') + ->assertSessionHas('error', 'You can only post a maximum of 5 threads per day.'); +})->only(); + test('users can edit a thread', function () { $user = $this->createUser(); $tag = Tag::factory()->create(['name' => 'Test Tag']); From 9e1f4a0e009cc7a183af116101e83bc2ad5790ff Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 1 Nov 2024 11:20:51 +0100 Subject: [PATCH 5/5] wip --- app/Http/Controllers/Forum/ThreadsController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Forum/ThreadsController.php b/app/Http/Controllers/Forum/ThreadsController.php index 2552585a2..fdf9d76da 100644 --- a/app/Http/Controllers/Forum/ThreadsController.php +++ b/app/Http/Controllers/Forum/ThreadsController.php @@ -81,7 +81,7 @@ public function show(Thread $thread) return view('forum.threads.show', compact('thread', 'moderators')); } - public function create() + public function create(): RedirectResponse|View { if (Auth::user()->hasTooManyThreadsToday()) { $this->error('You can only post a maximum of 5 threads per day.');