diff --git a/app/Http/Controllers/Articles/ArticlesController.php b/app/Http/Controllers/Articles/ArticlesController.php index f106566d0..7a1757fc7 100644 --- a/app/Http/Controllers/Articles/ArticlesController.php +++ b/app/Http/Controllers/Articles/ArticlesController.php @@ -45,22 +45,20 @@ public function index(Request $request) ->latest('approved_at') ->{$filter}(); - $tags = Tag::whereHas('articles', function ($query) { - $query->published(); - })->orderBy('name')->get(); + $tags = Tag::whereHas('articles', fn ($query) => $query->published()) + ->orderBy('name') + ->get(); if ($activeTag = Tag::where('slug', $request->tag)->first()) { $articles->forTag($activeTag->slug()); } - $moderators = Cache::remember('moderators', now()->addMinutes(30), function () { - return User::moderators()->get(); - }); - $canonical = canonical('articles', ['filter' => $filter, 'tag' => $activeTag?->slug()]); - $topAuthors = Cache::remember('topAuthors', now()->addMinutes(30), function () { - return User::mostSubmissionsInLastDays(365)->take(5)->get(); - }); + $topAuthors = Cache::remember( + 'topAuthors', + now()->addMinutes(30), + fn () => User::mostSubmissionsInLastDays(365)->take(5)->get() + ); return view('articles.overview', [ 'pinnedArticles' => $pinnedArticles, @@ -68,7 +66,6 @@ public function index(Request $request) 'tags' => $tags, 'activeTag' => $activeTag, 'filter' => $filter, - 'moderators' => $moderators, 'canonical' => $canonical, 'topAuthors' => $topAuthors, ]); @@ -155,7 +152,7 @@ public function update(ArticleRequest $request, Article $article) $article = $article->fresh(); - if ($wasNotPreviouslySubmitted && $request->shouldBeSubmitted()) { + if ($wasNotPreviouslySubmitted && $request->shouldBeSubmitted() && $article->isNotApproved()) { $this->success('Thank you for submitting, unfortunately we can\'t accept every submission. You\'ll only hear back from us when we accept your article.'); } else { $this->success('Article successfully updated!'); diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 7fa9fdd22..3a844c5b7 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -13,43 +13,34 @@ class HomeController extends Controller { public function show() { - $communityMembers = Cache::remember('communityMembers', now()->addMinutes(5), function () { - return User::withCounts() - ->hasActivity() - ->notBanned() - ->inRandomOrder() - ->take(100) - ->get() - ->chunk(20); - }); + $communityMembers = Cache::remember( + 'communityMembers', + now()->addMinutes(5), + fn () => User::notBanned()->inRandomOrder()->take(100)->get()->chunk(20) + ); - $totalUsers = Cache::remember('totalUsers', now()->addDay(), function () { - return number_format(User::notBanned()->count()); - }); + $totalUsers = Cache::remember('totalUsers', now()->addDay(), fn () => number_format(User::notBanned()->count())); - $totalThreads = Cache::remember('totalThreads', now()->addDay(), function () { - return number_format(Thread::count()); - }); + $totalThreads = Cache::remember('totalThreads', now()->addDay(), fn () => number_format(Thread::count())); - $totalReplies = Cache::remember('totalReplies', now()->addDay(), function () { - return number_format(Reply::count()); - }); + $totalReplies = Cache::remember('totalReplies', now()->addDay(), fn () => number_format(Reply::count())); - $latestThreads = Cache::remember('latestThreads', now()->addHour(), function () { - return Thread::whereNull('solution_reply_id') + $latestThreads = Cache::remember( + 'latestThreads', + now()->addHour(), + fn () => Thread::whereNull('solution_reply_id') ->whereBetween('threads.created_at', [now()->subMonth(), now()]) ->unlocked() ->inRandomOrder() ->limit(3) - ->get(); - }); + ->get() + ); - $latestArticles = Cache::remember('latestArticles', now()->addHour(), function () { - return Article::published() - ->recent() - ->limit(4) - ->get(); - }); + $latestArticles = Cache::remember( + 'latestArticles', + now()->addHour(), + fn () => Article::published()->recent()->limit(4)->get() + ); return view('home', [ 'communityMembers' => $communityMembers, diff --git a/app/Jobs/CreateArticle.php b/app/Jobs/CreateArticle.php index 601fb58d2..25b5236c7 100644 --- a/app/Jobs/CreateArticle.php +++ b/app/Jobs/CreateArticle.php @@ -69,6 +69,6 @@ public function handle(): void private function canBeAutoApproved(): bool { - return $this->shouldBeSubmitted && $this->author->canVerifiedAuthorPublishMoreArticleToday(); + return $this->shouldBeSubmitted && $this->author->canVerifiedAuthorPublishMoreArticlesToday(); } } diff --git a/app/Jobs/UpdateArticle.php b/app/Jobs/UpdateArticle.php index 17b12bc44..a73d03f14 100644 --- a/app/Jobs/UpdateArticle.php +++ b/app/Jobs/UpdateArticle.php @@ -53,9 +53,12 @@ public function handle(): void if ($this->shouldUpdateSubmittedAt()) { $this->article->submitted_at = now(); + $this->article->approved_at = $this->canBeAutoApproved() ? now() : null; $this->article->save(); - event(new ArticleWasSubmittedForApproval($this->article)); + if ($this->article->isAwaitingApproval()) { + event(new ArticleWasSubmittedForApproval($this->article)); + } } $this->article->syncTags($this->tags); @@ -69,4 +72,9 @@ private function shouldUpdateSubmittedAt(): bool { return $this->shouldBeSubmitted && $this->article->isNotSubmitted(); } + + private function canBeAutoApproved(): bool + { + return $this->article->author()->canVerifiedAuthorPublishMoreArticlesToday(); + } } diff --git a/app/Models/Article.php b/app/Models/Article.php index b6a3f0cc0..ad6aad1da 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -196,7 +196,7 @@ public function isShared(): bool public function isAwaitingApproval(): bool { - return $this->isSubmitted() && $this->isNotApproved() && $this->isNotDeclined() && ! $this->author()->canVerifiedAuthorPublishMoreArticleToday(); + return $this->isSubmitted() && $this->isNotApproved() && $this->isNotDeclined(); } public function isNotAwaitingApproval(): bool diff --git a/app/Models/User.php b/app/Models/User.php index c7a4dae8b..c43b35dad 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -317,7 +317,7 @@ public function isVerifiedAuthor(): bool return ! is_null($this->author_verified_at) || $this->isAdmin(); } - public function canVerifiedAuthorPublishMoreArticleToday(): bool + public function canVerifiedAuthorPublishMoreArticlesToday(): bool { if ($this->isAdmin()) { return true; @@ -364,13 +364,19 @@ public function scopeMostSolutions(Builder $query, ?int $inLastDays = null) public function scopeMostSubmissions(Builder $query, ?int $inLastDays = null) { - return $query->withCount(['articles as articles_count' => function ($query) use ($inLastDays) { - if ($inLastDays) { - $query->where('articles.approved_at', '>', now()->subDays($inLastDays)); - } + return $query + ->selectRaw('users.*, COUNT(DISTINCT articles.id) AS articles_count') + ->join('articles', 'articles.author_id', '=', 'users.id') + ->where(function ($query) use ($inLastDays) { + if ($inLastDays) { + $query->where('articles.approved_at', '>', now()->subDays($inLastDays)); + } - return $query; - }])->orderBy('articles_count', 'desc'); + return $query; + }) + ->groupBy('users.id') + ->having('articles_count', '>', 0) + ->orderBy('articles_count', 'desc'); } public function scopeMostSolutionsInLastDays(Builder $query, int $days) @@ -397,26 +403,6 @@ public function toSearchableArray(): array ]; } - public function scopeWithCounts(Builder $query) - { - return $query->withCount([ - 'threadsRelation as threads_count', - 'replyAble as replies_count', - 'replyAble as solutions_count' => function (Builder $query) { - return $query->join('threads', 'threads.solution_reply_id', '=', 'replies.id') - ->where('replyable_type', 'threads'); - }, - ]); - } - - public function scopeHasActivity(Builder $query) - { - return $query->where(function ($query) { - $query->has('threadsRelation') - ->orHas('replyAble'); - }); - } - public function scopeModerators(Builder $query) { return $query->whereIn('type', [ diff --git a/resources/css/app.css b/resources/css/app.css index 3ff58d771..60e68b32b 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -103,17 +103,6 @@ svg .secondary { @apply outline-hidden bg-gray-100; } -.member:after { - bottom: -1rem; - content: ' '; - display: block; - left: 7rem; - position: absolute; - border-color: #f9fafb transparent transparent transparent; - border-style: solid; - border-width: 0.5rem; -} - /** Choices.js **/ .choices__input.choices__input--cloned { @apply hidden; diff --git a/resources/views/components/community-member.blade.php b/resources/views/components/community-member.blade.php index 8e4ece2b0..2b5fcf82e 100644 --- a/resources/views/components/community-member.blade.php +++ b/resources/views/components/community-member.blade.php @@ -1,14 +1,7 @@
- - merge(['class' => 'member w-64 shadow-xl rounded-sm']) }}> -
-
- - {{ $user->solutions_count }} - - - Solutions -
- -
- - {{ $user->threads_count }} - - - Threads -
- -
- - {{ $user->replies_count }} - - - Replies -
-
-
{{ $user->username() }} diff --git a/tests/Feature/ArticleTest.php b/tests/Feature/ArticleTest.php index 439e7b6a4..0206b5754 100644 --- a/tests/Feature/ArticleTest.php +++ b/tests/Feature/ArticleTest.php @@ -594,7 +594,7 @@ 'submitted_at' => now()->addMinutes(1), // after verification ]); - expect($author->canVerifiedAuthorPublishMoreArticleToday())->toBeFalse(); + expect($author->canVerifiedAuthorPublishMoreArticlesToday())->toBeFalse(); }); test('verified authors skip the approval message when submitting new article', function () {