From 65965690882e23f0ba21d5b163d63aade537f6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ca=C5=82ka?= Date: Mon, 6 Nov 2023 16:32:29 +0100 Subject: [PATCH 1/5] fix: correct PostWasApproved event trigger condition Ensure the PostWasApproved event is only raised for posts that are not hidden. This fixes the issue where the event was incorrectly triggered for hidden posts. Additionally, the post's approval status is set to true upon deletion to remove any pending approval status. --- extensions/approval/src/Listener/ApproveContent.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/approval/src/Listener/ApproveContent.php b/extensions/approval/src/Listener/ApproveContent.php index e0b996f22f..72e3760c8d 100755 --- a/extensions/approval/src/Listener/ApproveContent.php +++ b/extensions/approval/src/Listener/ApproveContent.php @@ -39,7 +39,9 @@ public function approvePost(Saving $event) if (! empty($isApproved)) { $post->is_approved = true; - $post->raise(new PostWasApproved($post, $event->actor)); + if(! $post->hidden_at) { + $post->raise(new PostWasApproved($post, $event->actor)); + } } } } From 3bbd1f7d93fc824cb8b2add61d0dfd24fe056420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ca=C5=82ka?= Date: Mon, 6 Nov 2023 21:35:56 +0100 Subject: [PATCH 2/5] fix: Implement PostWasUnapproved event for all unapproved posts, hiding discussions for unapproved initial posts Introduces the PostWasUnapproved event, fired upon every post unapproval. Specifically, when the unapproved post is the initial post of a discussion, this event also hides the entire discussion. This change ensures that unapproved initial posts do not leave their discussions visible on the forum. --- extensions/akismet/extend.php | 4 +- .../akismet/src/Listener/SubmitSpam.php | 4 +- extensions/approval/extend.php | 2 + .../approval/src/Event/PostWasUnapproved.php | 38 +++++++++++++++++ .../approval/src/Listener/ApproveContent.php | 4 ++ .../UpdateDiscussionAfterPostApproval.php | 38 ++++++----------- .../UpdateDiscussionAfterPostUnapproval.php | 32 +++++++++++++++ .../approval/src/RefreshesDiscussionTrait.php | 41 +++++++++++++++++++ 8 files changed, 133 insertions(+), 30 deletions(-) create mode 100644 extensions/approval/src/Event/PostWasUnapproved.php create mode 100644 extensions/approval/src/Listener/UpdateDiscussionAfterPostUnapproval.php create mode 100644 extensions/approval/src/RefreshesDiscussionTrait.php diff --git a/extensions/akismet/extend.php b/extensions/akismet/extend.php index d233931b42..4503f266f7 100644 --- a/extensions/akismet/extend.php +++ b/extensions/akismet/extend.php @@ -10,8 +10,8 @@ use Flarum\Akismet\Listener; use Flarum\Akismet\Provider\AkismetProvider; use Flarum\Approval\Event\PostWasApproved; +use Flarum\Approval\Event\PostWasUnapproved; use Flarum\Extend; -use Flarum\Post\Event\Hidden; use Flarum\Post\Event\Saving; use Flarum\Post\Post; @@ -25,7 +25,7 @@ new Extend\Locales(__DIR__.'/locale'), (new Extend\Event()) - ->listen(Hidden::class, Listener\SubmitSpam::class) + ->listen(PostWasUnapproved::class, Listener\SubmitSpam::class) ->listen(PostWasApproved::class, Listener\SubmitHam::class) ->listen(Saving::class, Listener\ValidatePost::class), diff --git a/extensions/akismet/src/Listener/SubmitSpam.php b/extensions/akismet/src/Listener/SubmitSpam.php index 732a17f70b..213736c4e9 100644 --- a/extensions/akismet/src/Listener/SubmitSpam.php +++ b/extensions/akismet/src/Listener/SubmitSpam.php @@ -10,7 +10,7 @@ namespace Flarum\Akismet\Listener; use Flarum\Akismet\Akismet; -use Flarum\Post\Event\Hidden; +use Flarum\Approval\Event\PostWasUnapproved; class SubmitSpam { @@ -24,7 +24,7 @@ public function __construct(Akismet $akismet) $this->akismet = $akismet; } - public function handle(Hidden $event) + public function handle(PostWasUnapproved $event) { if (! $this->akismet->isConfigured()) { return; diff --git a/extensions/approval/extend.php b/extensions/approval/extend.php index c18e612a82..e72892573e 100644 --- a/extensions/approval/extend.php +++ b/extensions/approval/extend.php @@ -11,6 +11,7 @@ use Flarum\Api\Serializer\PostSerializer; use Flarum\Approval\Access; use Flarum\Approval\Event\PostWasApproved; +use Flarum\Approval\Event\PostWasUnapproved; use Flarum\Approval\Listener; use Flarum\Discussion\Discussion; use Flarum\Extend; @@ -52,6 +53,7 @@ (new Extend\Event()) ->listen(PostWasApproved::class, Listener\UpdateDiscussionAfterPostApproval::class) + ->listen(PostWasUnapproved::class, Listener\UpdateDiscussionAfterPostUnapproval::class) ->subscribe(Listener\ApproveContent::class) ->subscribe(Listener\UnapproveNewContent::class), diff --git a/extensions/approval/src/Event/PostWasUnapproved.php b/extensions/approval/src/Event/PostWasUnapproved.php new file mode 100644 index 0000000000..2f69867640 --- /dev/null +++ b/extensions/approval/src/Event/PostWasUnapproved.php @@ -0,0 +1,38 @@ +post = $post; + $this->actor = $actor; + } +} diff --git a/extensions/approval/src/Listener/ApproveContent.php b/extensions/approval/src/Listener/ApproveContent.php index 72e3760c8d..d72fe0609e 100755 --- a/extensions/approval/src/Listener/ApproveContent.php +++ b/extensions/approval/src/Listener/ApproveContent.php @@ -10,6 +10,7 @@ namespace Flarum\Approval\Listener; use Flarum\Approval\Event\PostWasApproved; +use Flarum\Approval\Event\PostWasUnapproved; use Flarum\Post\Event\Saving; use Illuminate\Contracts\Events\Dispatcher; @@ -37,10 +38,13 @@ public function approvePost(Saving $event) } if (! empty($isApproved)) { + // Set the post's approval status to true to clear any pending approval status, even if the post is hidden. $post->is_approved = true; if(! $post->hidden_at) { $post->raise(new PostWasApproved($post, $event->actor)); + } else { + $post->raise(new PostWasUnapproved($post, $event->actor)); } } } diff --git a/extensions/approval/src/Listener/UpdateDiscussionAfterPostApproval.php b/extensions/approval/src/Listener/UpdateDiscussionAfterPostApproval.php index 0db738ae5f..8ba7244274 100644 --- a/extensions/approval/src/Listener/UpdateDiscussionAfterPostApproval.php +++ b/extensions/approval/src/Listener/UpdateDiscussionAfterPostApproval.php @@ -10,36 +10,22 @@ namespace Flarum\Approval\Listener; use Flarum\Approval\Event\PostWasApproved; +use Flarum\Approval\RefreshesDiscussionTrait; class UpdateDiscussionAfterPostApproval { + use RefreshesDiscussionTrait; + public function handle(PostWasApproved $event) { - $post = $event->post; - $discussion = $post->discussion; - $user = $discussion->user; - - $discussion->refreshCommentCount(); - $discussion->refreshLastPost(); - - if ($post->number === 1) { - $discussion->is_approved = true; - - $discussion->afterSave(function () use ($user) { - $user->refreshDiscussionCount(); - }); - } - - $discussion->save(); - - if ($discussion->user) { - $user->refreshCommentCount(); - $user->save(); - } - - if ($post->user) { - $post->user->refreshCommentCount(); - $post->user->save(); - } + $this->refreshAndSaveDiscussion($event->post, function ($post, $discussion, $user) { + if ($post->number === 1) { + $discussion->is_approved = true; + + $discussion->afterSave(function () use ($user) { + $user->refreshDiscussionCount(); + }); + } + }); } } diff --git a/extensions/approval/src/Listener/UpdateDiscussionAfterPostUnapproval.php b/extensions/approval/src/Listener/UpdateDiscussionAfterPostUnapproval.php new file mode 100644 index 0000000000..dea16f1bdc --- /dev/null +++ b/extensions/approval/src/Listener/UpdateDiscussionAfterPostUnapproval.php @@ -0,0 +1,32 @@ +refreshAndSaveDiscussion($event->post,function ($post, $discussion, $user) { + if ($post->number === 1) { + $discussion->is_approved = true; + $discussion->hide(); + + $discussion->afterSave(function () use ($user) { + $user->refreshDiscussionCount(); + }); + } + }); + } +} diff --git a/extensions/approval/src/RefreshesDiscussionTrait.php b/extensions/approval/src/RefreshesDiscussionTrait.php new file mode 100644 index 0000000000..877d81671a --- /dev/null +++ b/extensions/approval/src/RefreshesDiscussionTrait.php @@ -0,0 +1,41 @@ +discussion; + $user = $discussion->user; + + $discussion->refreshCommentCount(); + $discussion->refreshLastPost(); + + if ($beforeDiscussionSaveCallback) { + $beforeDiscussionSaveCallback($post, $discussion, $user); + } + + $discussion->save(); + + if ($discussion->user) { + $user->refreshCommentCount(); + $user->save(); + } + + if ($post->user) { + $post->user->refreshCommentCount(); + $post->user->save(); + } + } +} From d21770f1c340514566542cd1d3ec28c16077aea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ca=C5=82ka?= Date: Fri, 10 Nov 2023 13:21:58 +0100 Subject: [PATCH 3/5] Revert "fix: Implement PostWasUnapproved event for all unapproved posts, hiding discussions for unapproved initial posts" This reverts commit 3bbd1f7d93fc824cb8b2add61d0dfd24fe056420. --- extensions/akismet/extend.php | 4 +- .../akismet/src/Listener/SubmitSpam.php | 4 +- extensions/approval/extend.php | 2 - .../approval/src/Event/PostWasUnapproved.php | 38 ----------------- .../approval/src/Listener/ApproveContent.php | 4 -- .../UpdateDiscussionAfterPostApproval.php | 38 +++++++++++------ .../UpdateDiscussionAfterPostUnapproval.php | 32 --------------- .../approval/src/RefreshesDiscussionTrait.php | 41 ------------------- 8 files changed, 30 insertions(+), 133 deletions(-) delete mode 100644 extensions/approval/src/Event/PostWasUnapproved.php delete mode 100644 extensions/approval/src/Listener/UpdateDiscussionAfterPostUnapproval.php delete mode 100644 extensions/approval/src/RefreshesDiscussionTrait.php diff --git a/extensions/akismet/extend.php b/extensions/akismet/extend.php index 4503f266f7..d233931b42 100644 --- a/extensions/akismet/extend.php +++ b/extensions/akismet/extend.php @@ -10,8 +10,8 @@ use Flarum\Akismet\Listener; use Flarum\Akismet\Provider\AkismetProvider; use Flarum\Approval\Event\PostWasApproved; -use Flarum\Approval\Event\PostWasUnapproved; use Flarum\Extend; +use Flarum\Post\Event\Hidden; use Flarum\Post\Event\Saving; use Flarum\Post\Post; @@ -25,7 +25,7 @@ new Extend\Locales(__DIR__.'/locale'), (new Extend\Event()) - ->listen(PostWasUnapproved::class, Listener\SubmitSpam::class) + ->listen(Hidden::class, Listener\SubmitSpam::class) ->listen(PostWasApproved::class, Listener\SubmitHam::class) ->listen(Saving::class, Listener\ValidatePost::class), diff --git a/extensions/akismet/src/Listener/SubmitSpam.php b/extensions/akismet/src/Listener/SubmitSpam.php index 213736c4e9..732a17f70b 100644 --- a/extensions/akismet/src/Listener/SubmitSpam.php +++ b/extensions/akismet/src/Listener/SubmitSpam.php @@ -10,7 +10,7 @@ namespace Flarum\Akismet\Listener; use Flarum\Akismet\Akismet; -use Flarum\Approval\Event\PostWasUnapproved; +use Flarum\Post\Event\Hidden; class SubmitSpam { @@ -24,7 +24,7 @@ public function __construct(Akismet $akismet) $this->akismet = $akismet; } - public function handle(PostWasUnapproved $event) + public function handle(Hidden $event) { if (! $this->akismet->isConfigured()) { return; diff --git a/extensions/approval/extend.php b/extensions/approval/extend.php index e72892573e..c18e612a82 100644 --- a/extensions/approval/extend.php +++ b/extensions/approval/extend.php @@ -11,7 +11,6 @@ use Flarum\Api\Serializer\PostSerializer; use Flarum\Approval\Access; use Flarum\Approval\Event\PostWasApproved; -use Flarum\Approval\Event\PostWasUnapproved; use Flarum\Approval\Listener; use Flarum\Discussion\Discussion; use Flarum\Extend; @@ -53,7 +52,6 @@ (new Extend\Event()) ->listen(PostWasApproved::class, Listener\UpdateDiscussionAfterPostApproval::class) - ->listen(PostWasUnapproved::class, Listener\UpdateDiscussionAfterPostUnapproval::class) ->subscribe(Listener\ApproveContent::class) ->subscribe(Listener\UnapproveNewContent::class), diff --git a/extensions/approval/src/Event/PostWasUnapproved.php b/extensions/approval/src/Event/PostWasUnapproved.php deleted file mode 100644 index 2f69867640..0000000000 --- a/extensions/approval/src/Event/PostWasUnapproved.php +++ /dev/null @@ -1,38 +0,0 @@ -post = $post; - $this->actor = $actor; - } -} diff --git a/extensions/approval/src/Listener/ApproveContent.php b/extensions/approval/src/Listener/ApproveContent.php index d72fe0609e..72e3760c8d 100755 --- a/extensions/approval/src/Listener/ApproveContent.php +++ b/extensions/approval/src/Listener/ApproveContent.php @@ -10,7 +10,6 @@ namespace Flarum\Approval\Listener; use Flarum\Approval\Event\PostWasApproved; -use Flarum\Approval\Event\PostWasUnapproved; use Flarum\Post\Event\Saving; use Illuminate\Contracts\Events\Dispatcher; @@ -38,13 +37,10 @@ public function approvePost(Saving $event) } if (! empty($isApproved)) { - // Set the post's approval status to true to clear any pending approval status, even if the post is hidden. $post->is_approved = true; if(! $post->hidden_at) { $post->raise(new PostWasApproved($post, $event->actor)); - } else { - $post->raise(new PostWasUnapproved($post, $event->actor)); } } } diff --git a/extensions/approval/src/Listener/UpdateDiscussionAfterPostApproval.php b/extensions/approval/src/Listener/UpdateDiscussionAfterPostApproval.php index 8ba7244274..0db738ae5f 100644 --- a/extensions/approval/src/Listener/UpdateDiscussionAfterPostApproval.php +++ b/extensions/approval/src/Listener/UpdateDiscussionAfterPostApproval.php @@ -10,22 +10,36 @@ namespace Flarum\Approval\Listener; use Flarum\Approval\Event\PostWasApproved; -use Flarum\Approval\RefreshesDiscussionTrait; class UpdateDiscussionAfterPostApproval { - use RefreshesDiscussionTrait; - public function handle(PostWasApproved $event) { - $this->refreshAndSaveDiscussion($event->post, function ($post, $discussion, $user) { - if ($post->number === 1) { - $discussion->is_approved = true; - - $discussion->afterSave(function () use ($user) { - $user->refreshDiscussionCount(); - }); - } - }); + $post = $event->post; + $discussion = $post->discussion; + $user = $discussion->user; + + $discussion->refreshCommentCount(); + $discussion->refreshLastPost(); + + if ($post->number === 1) { + $discussion->is_approved = true; + + $discussion->afterSave(function () use ($user) { + $user->refreshDiscussionCount(); + }); + } + + $discussion->save(); + + if ($discussion->user) { + $user->refreshCommentCount(); + $user->save(); + } + + if ($post->user) { + $post->user->refreshCommentCount(); + $post->user->save(); + } } } diff --git a/extensions/approval/src/Listener/UpdateDiscussionAfterPostUnapproval.php b/extensions/approval/src/Listener/UpdateDiscussionAfterPostUnapproval.php deleted file mode 100644 index dea16f1bdc..0000000000 --- a/extensions/approval/src/Listener/UpdateDiscussionAfterPostUnapproval.php +++ /dev/null @@ -1,32 +0,0 @@ -refreshAndSaveDiscussion($event->post,function ($post, $discussion, $user) { - if ($post->number === 1) { - $discussion->is_approved = true; - $discussion->hide(); - - $discussion->afterSave(function () use ($user) { - $user->refreshDiscussionCount(); - }); - } - }); - } -} diff --git a/extensions/approval/src/RefreshesDiscussionTrait.php b/extensions/approval/src/RefreshesDiscussionTrait.php deleted file mode 100644 index 877d81671a..0000000000 --- a/extensions/approval/src/RefreshesDiscussionTrait.php +++ /dev/null @@ -1,41 +0,0 @@ -discussion; - $user = $discussion->user; - - $discussion->refreshCommentCount(); - $discussion->refreshLastPost(); - - if ($beforeDiscussionSaveCallback) { - $beforeDiscussionSaveCallback($post, $discussion, $user); - } - - $discussion->save(); - - if ($discussion->user) { - $user->refreshCommentCount(); - $user->save(); - } - - if ($post->user) { - $post->user->refreshCommentCount(); - $post->user->save(); - } - } -} From 9cd61c7b00201ad7ff2aeb1326764bbb1838d58c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ca=C5=82ka?= Date: Fri, 10 Nov 2023 13:37:53 +0100 Subject: [PATCH 4/5] fix(approval): post approved event triggered when not approving Co-authored-by: SychO9 --- .../approval/src/Listener/ApproveContent.php | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/extensions/approval/src/Listener/ApproveContent.php b/extensions/approval/src/Listener/ApproveContent.php index 72e3760c8d..28ffd444a6 100755 --- a/extensions/approval/src/Listener/ApproveContent.php +++ b/extensions/approval/src/Listener/ApproveContent.php @@ -11,35 +11,53 @@ use Flarum\Approval\Event\PostWasApproved; use Flarum\Post\Event\Saving; +use Flarum\User\Exception\PermissionDeniedException; use Illuminate\Contracts\Events\Dispatcher; class ApproveContent { /** - * @param Dispatcher $events + * @param Dispatcher $events */ public function subscribe(Dispatcher $events) { $events->listen(Saving::class, [$this, 'approvePost']); } + /** + * @throws PermissionDeniedException + */ public function approvePost(Saving $event) { $attributes = $event->data['attributes']; $post = $event->post; + // Nothing to do if it is already approved. + if ($post->is_approved) { + return; + } + + /* + * We approve a post in one of two cases: + * - The post was unapproved and the allowed action is approving it. We trigger an event. + * - The post was unapproved and the allowed actor is hiding or un-hiding it. + * We approve it silently if the action is unhiding. + */ + $approvingSilently = false; + if (isset($attributes['isApproved'])) { $event->actor->assertCan('approve', $post); $isApproved = (bool) $attributes['isApproved']; - } elseif (! empty($attributes['isHidden']) && $event->actor->can('approve', $post)) { + } elseif (isset($attributes['isHidden']) && $event->actor->can('approve', $post)) { $isApproved = true; + $approvingSilently = $attributes['isHidden']; } if (! empty($isApproved)) { $post->is_approved = true; - if(! $post->hidden_at) { + if (! $approvingSilently) { $post->raise(new PostWasApproved($post, $event->actor)); } } From 905a7b4f1b41a2c88c8657284adb64bac28a9587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Ca=C5=82ka?= Date: Fri, 10 Nov 2023 14:02:46 +0100 Subject: [PATCH 5/5] style: fix code formatting --- extensions/approval/src/Listener/ApproveContent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/approval/src/Listener/ApproveContent.php b/extensions/approval/src/Listener/ApproveContent.php index 28ffd444a6..d13d9d19ed 100755 --- a/extensions/approval/src/Listener/ApproveContent.php +++ b/extensions/approval/src/Listener/ApproveContent.php @@ -17,7 +17,7 @@ class ApproveContent { /** - * @param Dispatcher $events + * @param Dispatcher $events */ public function subscribe(Dispatcher $events) {